3

我已经实现了一个自定义 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 始终等于位置的偏移量。

4

1 回答 1

2

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

为了解决这个问题,我会考虑使用视图上的标签字段来存储当前项目 - 然后在删除操作中使用它。

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 调用将重置所有显示的列表视图项)
  • 我已经将这个简单的 JavaContainer 用于 Tag 字段 - https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxJavaContainer.cs
  • 如果您需要将标签用于其他目的,那么 Android/MonoDroid 允许您使用 SetTag(key,obj) 存储多个标签
于 2012-11-14T08:15:29.397 回答