使用 SearchView xamarin 过滤 ListView [英] Filter ListView with SearchView xamarin

查看:28
本文介绍了使用 SearchView xamarin 过滤 ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过 Searchview 过滤 Listview

我将以下适配器用于过滤器,如果我没有对适配器添加任何新内容,它就可以工作

当我向Listview添加新项目时,搜索完全停止,直到我在添加、修改或删除它后重新启动程序

完整代码

如果您想根据您的适配器将项目添加到列表视图中,您应该像以下代码一样在适配器中添加项目.

 公共类 TableItemAdapter : BaseAdapter, IFilterable{公共列表_originalData;公共列表_项目;私有只读 Activity _context;public TableItemAdapter(活动活动,IEnumerabletableitems){_items = tableitems.ToList();_context = 活动;Filter = new TableItemFilter(this);}//给`_items`添加数据,listview会更新,如果在activity中添加数据,//有两个不同的列表,所以列表视图不会更新.public void AddData(TableItem tableItem){_items.Add(tableItem);NotifyDataSetChanged();}公共覆盖 TableItem this[int position]{得到 { 返回 _items[位置];}}公共过滤器过滤器{获取;私人订制;}公共覆盖整数计数{得到 { 返回 _items.Count;}}公共覆盖长 GetItemId(int position){返回位置;}public override View GetView(int position, View convertView, ViewGroup parent){var item = _items[位置];查看视图 = convertView;if (view == null)//没有视图可以重用,创建新的视图 = 转换视图 ??_context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);//view = _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);view.FindViewById(Resource.Id.Text1).Text = item.Heading;view.FindViewById(Resource.Id.Text2).Text = item.SubHeading;返回视图;}公共覆盖无效 NotifyDataSetChanged(){//this.NotifyDataSetChanged();base.NotifyDataSetChanged();}}公共类 TableItemFilter :Filter{私有只读 TableItemAdapter _adapter;公共 TableItemFilter(TableItemAdapter 适配器){_adapter = 适配器;}受保护的覆盖 FilterResults PerformFiltering(ICharSequence 约束){var returnObj = new FilterResults();var 结果 = new List();if (_adapter._originalData == null)_adapter._originalData = _adapter._items;if (constraint == null) return returnObj;if (_adapter._originalData != null && _adapter._originalData.Any()){结果.AddRange(_adapter._originalData.Where(项目 =>item.SubHeading.ToLower().Contains(constraint.ToString()) |item.Heading.ToLower().Contains(constraint.ToString())));}returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());returnObj.Count = results.Count;约束.处置();返回 returnObj;}protected override void PublishResults(ICharSequence 约束,FilterResults 结果){使用 (var 值 = results.Values)_adapter._items = values.ToArray().Select(r =>r.ToNetObject()).ToList();_adapter.NotifyDataSetChanged();//不要这样做,会看到 GREF 计数上升约束.处置();结果.处置();}}公共类 JavaHolder : Java.Lang.Object{公共只读对象实例;公共 JavaHolder(对象实例){实例 = 实例;}}公共静态类 ObjectExtensions{public static TObject ToNetObject(这个Java.Lang.Object值){如果(值 == 空)返回默认值(TObject);if (!(value 是 JavaHolder))throw new InvalidOperationException("无法转换为 .NET 对象.只能转换使用 .ToJavaObject() 创建的 Java.Lang.Object.");TObject returnVal;尝试 { returnVal = (TObject)((JavaHolder)value).Instance;}最后 { value.Dispose();}返回 returnVal;}public static Java.Lang.Object ToJavaObject(这个TObject值){if (Equals(value, default(TObject)) && !typeof(TObject).IsValueType)返回空;var holder = new JavaHolder(value);返回持有人;}}}

然后在活动中,您通过适配器添加数据.

 private void Button1_Click(object sender, System.EventArgs e){tableItemAdapter.AddData(new TableItem() { Heading = "test1222", SubHeading = "sub Test" });}

这是我的演示,你可以下载.https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/XAListViewSearchDemo.zip

I want to filter Listview by Searchview

I use the following Adapter for the filter and it works if I haven't made any new additions to the adapter

When I add a new item to Listview, the search stops completely until I restart the program after adding, modifying or deleting it

full code

adapter class

解决方案

Do you want to achieve the result like following GIF?

If you want to add the item to the listview, based on your adapter, you should item in the adapter like following code.

   public class TableItemAdapter : BaseAdapter<TableItem>, IFilterable
    {
        public List<TableItem> _originalData;
        public List<TableItem> _items;
        private readonly Activity _context;


        public TableItemAdapter(Activity activity, IEnumerable<TableItem> tableitems)
        {

            _items = tableitems.ToList();
            _context = activity;

            Filter = new TableItemFilter(this);
        }

        //Add data to the `_items`, listview will be updated, if add data in the activity, 
        //there are two different lists, so listview will not update.
        public void AddData(TableItem tableItem)
        {
            _items.Add(tableItem);
            NotifyDataSetChanged();
        }

        public override TableItem this[int position]
        {
            get { return _items[position]; }
        }

        public Filter Filter { get; private set; }

        public override int Count
        {
            get { return _items.Count; }
        }

        public override long GetItemId(int position)
        {
            return position;
        }



        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            var item = _items[position];

            View view = convertView;


            if (view == null) // no view to re-use, create new
                view = convertView ?? _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);
            //view = _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);
            view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
            view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading;


            return view;

        }
        public override void NotifyDataSetChanged()
        {
           // this.NotifyDataSetChanged();
          base.NotifyDataSetChanged();
        }
    }

    public class TableItemFilter :Filter
    {
        private readonly TableItemAdapter _adapter;
        public TableItemFilter(TableItemAdapter adapter)
        {
            _adapter = adapter;
        }

        protected override FilterResults PerformFiltering(ICharSequence constraint)
        {
            var returnObj = new FilterResults();
            var results = new List<TableItem>();


            if (_adapter._originalData == null)
                _adapter._originalData = _adapter._items;

            if (constraint == null) return returnObj;

            if (_adapter._originalData != null && _adapter._originalData.Any())
            {

                results.AddRange(
                    _adapter._originalData.Where(
                        item => item.SubHeading.ToLower().Contains(constraint.ToString()) | item.Heading.ToLower().Contains(constraint.ToString())));

            }


            returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());
            returnObj.Count = results.Count;

            constraint.Dispose();

            return returnObj;
        }



        protected override void PublishResults(ICharSequence constraint, FilterResults results)
        {
            using (var values = results.Values)
                _adapter._items = values.ToArray<Java.Lang.Object>().Select(r => r.ToNetObject<TableItem>()).ToList();

            _adapter.NotifyDataSetChanged();

            // Don't do this and see GREF counts rising
            constraint.Dispose();
            results.Dispose();
        }

    }

    public  class JavaHolder : Java.Lang.Object
    {
        public readonly object Instance;

        public JavaHolder(object instance)
        {
            Instance = instance;
        }


    }

    public static class ObjectExtensions
    {
        public static TObject ToNetObject<TObject>(this Java.Lang.Object value)
        {
            if (value == null)
                return default(TObject);

            if (!(value is JavaHolder))
                throw new InvalidOperationException("Unable to convert to .NET object. Only Java.Lang.Object created with .ToJavaObject() can be converted.");

            TObject returnVal;
            try { returnVal = (TObject)((JavaHolder)value).Instance; }
            finally { value.Dispose(); }
            return returnVal;
        }

        public static Java.Lang.Object ToJavaObject<TObject>(this TObject value)
        {
            if (Equals(value, default(TObject)) && !typeof(TObject).IsValueType)
                return null;

            var holder = new JavaHolder(value);

            return holder;
        }
    }
}

Then in the activity, you add the data by adapter.

 private void Button1_Click(object sender, System.EventArgs e)
        {

            tableItemAdapter.AddData(new TableItem() { Heading = "test1222", SubHeading = "sub Test" });


        }

Here is my demo, you can download it. https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/XAListViewSearchDemo.zip

这篇关于使用 SearchView xamarin 过滤 ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆