从列表视图项按钮中删除列表视图项

时间:2012-11-14 05:53:15

标签: c# android listview button xamarin.android

我已经实现了一个自定义BaseAdapter,它显示带有自定义布局的列表项。

一切正常但我试图在项目旁边添加一个删除按钮(我有),但是我在尝试让它工作时遇到了问题。

相关代码在这里:

    public List<OrderLineItem> Items
    {
        get;
        set;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        OrderLineItem item = GetItemAtPosition(position);

        var view = (convertView ??
            Context.LayoutInflater.Inflate(Resource.Layout.CustomListItem, parent, false)) as LinearLayout;

        // ..........
        var removeButton = view.FindViewById(Resource.Id.btnRemove) as Button;

        removeButton.Click += delegate
        {
            Items.RemoveAt(position);
            this.NotifyDataSetChanged();
        };

        // ...........

        return view;
    }

问题是我认为由于委托闭包,因为Items.Count总是等于位置的偏移量。

1 个答案:

答案 0 :(得分:2)

我认为您对导致问题的闭包的分析可能是正确的。

要解决这个问题,我会考虑使用View上的Tag字段来存储当前项目 - 然后在删除操作中使用它。

public override View GetView(int position, View convertView, ViewGroup parent)
{
    OrderLineItem item = GetItemAtPosition(position);

    var view = convertView;

    if (view == null)
    {
        view = Context.LayoutInflater.Inflate(Resource.Layout.CustomListItem, parent, false)) as LinearLayout;

        var removeButton = view.FindViewById(Resource.Id.btnRemove) as Button;

        removeButton.Click += (s, e) => {
            var originalView = (View)s;
            var originalItem = originalView.Tag as MvxJavaContainer<OrderLineItem>;
            Items.Remove(originalItem);
            this.NotifyDataSetChanged();
        };
    }

    // ...........
    var tagButton = view.FindViewById(Resource.Id.btnRemove) as Button;
    tagButton.Tag = new MvxJavaContainer<OrderLineItem>(item);

    return view;
}

注意:

  • Click事件处理程序只设置一次非常重要 - 每次使用和重用View时都不要设置。
  • 我决定使用Remove而不是RemoveAt,因为我觉得在项目N被移除的情况下更容易跟踪(然后N + 1变为N,N + 2变为N + 1等)。但是,我认为您可以相当轻松地使用RemoveAt(我认为NotifyDataSetChanged调用将重置所有显示的listview项目)
  • 我在标记字段中使用了这个简单的JavaContainer - https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxJavaContainer.cs
  • 如果您需要将Tag用于其他目的,那么Android / MonoDroid允许您使用SetTag(key,obj)存储多个标签