C# 在RecyclerView中搜索-Xamarin.Droid

C# 在RecyclerView中搜索-Xamarin.Droid,c#,android,xamarin,xamarin.android,C#,Android,Xamarin,Xamarin.android,我一直在寻找Xamarin通过回收视图进行搜索的方法。有人能给我介绍一下如何以Xamarin的方式实现这一功能的演示吗?我写了一个关于如何实现这一功能的简单演示,效果如。 你可以在这张照片上看到 有关更多信息,您可以阅读以下文档:在Xamarin.Android中,以及关于使用SearchView的过滤器aRecyclerView 感谢Xaver Kapeller的回答,他关于搜索RecyclerView的回答很棒,所以我决定将其翻译成Xamarin,以帮助更多的人 设置搜索视图 在文件夹res

我一直在寻找Xamarin通过回收视图进行搜索的方法。有人能给我介绍一下如何以Xamarin的方式实现这一功能的演示吗?

我写了一个关于如何实现这一功能的简单演示,效果如。 你可以在这张照片上看到

有关更多信息,您可以阅读以下文档:在Xamarin.Android中,以及关于使用
SearchView
的过滤器a
RecyclerView

感谢Xaver Kapeller的回答,他关于搜索
RecyclerView
的回答很棒,所以我决定将其翻译成Xamarin,以帮助更多的人

  • 设置
    搜索视图
  • 在文件夹
    res/menu
    中创建一个名为
    main.xml
    的新文件。在其中添加一个项目,并将
    actionViewClass
    设置为
    android.support.v7.widget.SearchView
    。由于您使用的是支持库,因此必须使用支持库的名称空间来设置
    actionViewClass
    属性。您的xml文件应如下所示:

     <?xml version="1.0" encoding="utf-8"?>
     <menu xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto">
         <item android:id="@+id/action_search"
               android:title="Search"
               android:icon="@android:drawable/ic_menu_search"
               app:showAsAction="always|collapseActionView"
               app:actionViewClass="android.support.v7.widget.SearchView" />
      </menu>
    
  • 设置
    适配器
  • 首先,添加将用于此示例的模型类:

    public class Chemical
    {
        public string Name { get; set; }
    
        public int DrawableId { get; set; }
    }
    
    这只是您的基本模型,它将在
    RecyclerView
    中显示文本。这是显示布局的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:padding="5dp">
        <ImageView
            android:id="@+id/chemImage"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignParentLeft="true"
            android:layout_margin="5dp" />
        <TextView
            android:id="@+id/chemName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/chemImage"
            android:layout_centerInParent="true"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp" />
     </RelativeLayout>
    
    三,实现
    RecyclerView.Adapter

    public class RecyclerViewAdapter : RecyclerView.Adapter, IFilterable
    {
        private List<Chemical> _originalData;
        private List<Chemical> _items;
        private readonly Activity _context;
    
        public Filter Filter { get; private set; }
    
        public RecyclerViewAdapter(Activity activity, IEnumerable<Chemical> chemicals)
        {
            _items = chemicals.OrderBy(s => s.Name).ToList();
            _context = activity;
    
            Filter = new ChemicalFilter(this);
        }
    
        public override long GetItemId(int position)
        {
            return position;
        }
    
    
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.Chemical, parent, false);
            ChemicalHolder vh = new ChemicalHolder(itemView);
            return vh;
        }
    
        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            ChemicalHolder vh = holder as ChemicalHolder;
    
            var chemical = _items[position];
    
            vh.Image.SetImageResource(chemical.DrawableId);
            vh.Caption.Text = chemical.Name;
        }
    
        public override int ItemCount
        {
            get { return _items.Count; }
        }
    
        public class ChemicalHolder{...
    
        private class ChemicalFilter{//Implement the Filter logic
     }
    
    公共类RecyclerViewAdapter:RecyclerView.Adapter,IFilterable { 私有列表_originalData; 私人物品清单; 私有只读活动\u上下文; 公共筛选器筛选器{get;private set;} 公共再生水(活动、可计量化学品) { _items=chemicals.OrderBy(s=>s.Name.ToList(); _上下文=活动; 过滤器=新的化学过滤器(本); } 公共覆盖长GetItemId(int位置) { 返回位置; } public override RecyclerView.ViewHolder OnCreateViewHolder(视图组父级,int-viewType) { View itemView=LayoutFlater.From(parent.Context)。充气(Resource.Layout.Chemical,parent,false); ChemicalHolder vh=新的ChemicalHolder(项目视图); 返回vh; } 公共覆盖无效OnBindViewHolder(RecyclerView.ViewHolder,int位置) { ChemicalHolder vh=作为ChemicalHolder的持有人; var化学品=_项目[位置]; vh.Image.SetImageResource(化学.可提取ID); vh.Caption.Text=化学品名称; } 公共覆盖int ItemCount { 获取{return\u items.Count;} } 公共类化学持有者{。。。 私有类ChemicalFilter{//实现过滤器逻辑 }
  • 实现过滤逻辑

    private class ChemicalFilter : Filter
    {
        private readonly RecyclerViewAdapter _adapter;
        public ChemicalFilter(RecyclerViewAdapter adapter)
        {
            _adapter = adapter;
        }
    
        protected override FilterResults PerformFiltering(ICharSequence constraint)
        {
            var returnObj = new FilterResults();
            var results = new List<Chemical>();
            if (_adapter._originalData == null)
                _adapter._originalData = _adapter._items;
    
            if (constraint == null) return returnObj;
    
            if (_adapter._originalData != null && _adapter._originalData.Any())
            {
                // Compare constraint to all names lowercased. 
                // It they are contained they are added to results.
                results.AddRange(
                    _adapter._originalData.Where(
                        chemical => chemical.Name.ToLower().Contains(constraint.ToString())));
            }
    
            // Nasty piece of .NET to Java wrapping, be careful with this!
            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<Chemical>()).ToList();
    
            _adapter.NotifyDataSetChanged();
    
            // Don't do this and see GREF counts rising
            constraint.Dispose();
            results.Dispose();
        }
    }
    
    专用类化学过滤器:过滤器
    {
    专用只读RecycleWebAdapter\u适配器;
    公共化学过滤器(再循环过滤器适配器)
    {
    _适配器=适配器;
    }
    受保护的覆盖筛选器结果性能筛选(ICharSequence约束)
    {
    var returnObj=new FilterResults();
    var results=新列表();
    if(_adapter._originalData==null)
    _适配器。\原始数据=\适配器。\项目;
    if(constraint==null)返回returnObj;
    if(_adapter._originalData!=null&&u adapter._originalData.Any())
    {
    //将约束与所有小写名称进行比较。
    //如果它们被包含,它们将被添加到结果中。
    results.AddRange(
    _适配器._originalData.Where(
    chemical=>chemical.Name.ToLower().Contains(constraint.ToString());
    }
    //讨厌的.NET到Java的包装,小心这个!
    returnObj.Values=FromArray(results.Select(r=>r.ToJavaObject()).ToArray());
    returnObj.Count=结果.Count;
    constraint.Dispose();
    返回OBJ;
    }
    受保护的覆盖无效PublishResults(ICharSequence约束、FilterResults结果)
    {
    使用(var值=results.values)
    _适配器。_items=values.ToArray()
    .Select(r=>r.ToNetObject()).ToList();
    _adapter.NotifyDataSetChanged();
    //不要这样做,就会看到格雷夫计数上升
    constraint.Dispose();
    结果:Dispose();
    }
    }
    
  • 使用它来实现此功能

        SetContentView(Resource.Layout.Main);
        SupportActionBar.SetDisplayShowHomeEnabled(true);
    
        var chemicals = new List<Chemical>
        {
            new Chemical {Name = "Niacin", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Biotin", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Chromichlorid", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Natriumselenit", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Manganosulfate", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Natriummolybdate", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Ergocalciferol", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Cyanocobalamin", DrawableId = Resource.Drawable.Icon},
        };
    
        _recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
        _adapter = new RecyclerViewAdapter(this,chemicals);
        _LayoutManager = new LinearLayoutManager(this);
        _recyclerView.SetLayoutManager(_LayoutManager);
        _recyclerView.SetAdapter(_adapter);//
    
    SetContentView(Resource.Layout.Main);
    SupportActionBar.SetDisplayShowHomeEnabled(真);
    var化学品=新列表
    {
    新化学品{Name=“Niacin”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Biotin”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Chromichlorid”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Natriumselenit”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“硫酸锰”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Natriummolybdate”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Ergocalciferol”,DrawableId=Resource.Drawable.Icon},
    新化学品{Name=“Cyanocobalamin”,DrawableId=Resource.Drawable.Icon},
    };
    _recyclerView=FindViewById(Resource.Id.recyclerView);
    _适配器=新的再循环适配器(此为化学品);
    _LayoutManager=新的LinearLayoutManager(此);
    _recyclerView.SetLayoutManager(\u LayoutManager);
    _recyclerView.SetAdapter(_adapter)//
    

  • 这是一个关于如何在Xamarin.Android中使用RecyclerView的和。@YorkShen不是关于如何使用它,而是使用搜索图标过滤回收器视图:)在这一行
    \u searchView.QueryTextChange+=(s,e)=>\u adapter.filter.InvokeFilter(e.NewText)
    从何处调用
    \u适配器
    OnCreate
    方法中初始化
    \u适配器
    \u适配器=新的回收服务适配器(此,化学品)
    。在此行
    中选择(r=>r.ToNetObjec
    
    private class ChemicalFilter : Filter
    {
        private readonly RecyclerViewAdapter _adapter;
        public ChemicalFilter(RecyclerViewAdapter adapter)
        {
            _adapter = adapter;
        }
    
        protected override FilterResults PerformFiltering(ICharSequence constraint)
        {
            var returnObj = new FilterResults();
            var results = new List<Chemical>();
            if (_adapter._originalData == null)
                _adapter._originalData = _adapter._items;
    
            if (constraint == null) return returnObj;
    
            if (_adapter._originalData != null && _adapter._originalData.Any())
            {
                // Compare constraint to all names lowercased. 
                // It they are contained they are added to results.
                results.AddRange(
                    _adapter._originalData.Where(
                        chemical => chemical.Name.ToLower().Contains(constraint.ToString())));
            }
    
            // Nasty piece of .NET to Java wrapping, be careful with this!
            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<Chemical>()).ToList();
    
            _adapter.NotifyDataSetChanged();
    
            // Don't do this and see GREF counts rising
            constraint.Dispose();
            results.Dispose();
        }
    }
    
        SetContentView(Resource.Layout.Main);
        SupportActionBar.SetDisplayShowHomeEnabled(true);
    
        var chemicals = new List<Chemical>
        {
            new Chemical {Name = "Niacin", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Biotin", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Chromichlorid", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Natriumselenit", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Manganosulfate", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Natriummolybdate", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Ergocalciferol", DrawableId = Resource.Drawable.Icon},
            new Chemical {Name = "Cyanocobalamin", DrawableId = Resource.Drawable.Icon},
        };
    
        _recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
        _adapter = new RecyclerViewAdapter(this,chemicals);
        _LayoutManager = new LinearLayoutManager(this);
        _recyclerView.SetLayoutManager(_LayoutManager);
        _recyclerView.SetAdapter(_adapter);//