【问题标题】:Removing a listview item from a listview item button从列表视图项按钮中删除列表视图项
【发布时间】:2012-11-14 05:53:15
【问题描述】:

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

【问题讨论】:

    标签: c# android listview button xamarin.android


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢斯图尔特。您可能想要更新您的视图。Tag = ... 在按钮上设置标签,因为 (s, e) => { s - 等于按钮作为发送者。
    • 已修复。谢谢。您可能还会在某些时候发现内联匿名函数会导致内存泄漏 - 我仍然不确定我是否理解其中的复杂性!
    猜你喜欢
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多