【问题标题】:Filterable with multi-select list可通过多选列表过滤
【发布时间】:2018-06-17 04:05:50
【问题描述】:

我想要一个带有搜索选项的多选微调器。我已经实现了一个带有搜索选项的微调器。我想要一些关于多选的帮助。

这是我的代码:

适配器类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using ViewModels;

namespace Adapters
{
    public class FilterableAdapter : ArrayAdapter, IFilterable
    {
        LayoutInflater inflater;
        Filter filter;
        Activity context;
        public List<FilterableListViewModel> AllItems;
        public List<FilterableListViewModel> MatchItems;

        public FilterableAdapter(Activity context, int txtViewResourceId, List<FilterableListViewModel> items) : base(context, txtViewResourceId, items)
        {
            inflater = context.LayoutInflater;
            filter = new SuggestionsFilter(this);
            AllItems = items;
            MatchItems = items;
        }

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

        public override Java.Lang.Object GetItem(int position)
        {
            return null;
        }

        public FilterableListViewModel GetMatchedItem(int position)
        {
            return MatchItems[position];
        }


        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View view = convertView;
            if (view == null)
                view = inflater.Inflate(Resource.Drawable.filterList_view, null);

            view.FindViewById<TextView>(Resource.Id.list_itemContent).Text = MatchItems[position].displayName;
            //if (!string.IsNullOrEmpty(MatchItems[position].subItem))
            //{
            //    view.FindViewById<TextView>(Resource.Id.list_subItemContent).Text = MatchItems[position].subItem;
            //}
            //else
            //{

            //    view.FindViewById<TextView>(Resource.Id.list_subItemContent).Visibility = ViewStates.Gone;
            //}
            return view;
        }

        public override Filter Filter
        {
            get
            {
                return filter;
            }
        }

        public void ResetSearch()
        {
            MatchItems = AllItems;
            NotifyDataSetChanged();
        }

        class SuggestionsFilter : Filter
        {
            readonly FilterableAdapter _adapter;

            public SuggestionsFilter(FilterableAdapter adapter) : base()
            {
                _adapter = adapter;
            }

            protected override Filter.FilterResults PerformFiltering(Java.Lang.ICharSequence constraint)
            {
                FilterResults results = new FilterResults();
                if (!String.IsNullOrEmpty(constraint.ToString()))
                {
                    var searchFor = constraint.ToString();
                    Console.WriteLine("searchFor:" + searchFor);
                    var matchList = new List<FilterableListViewModel>();
                    //var matches = _adapter.AllItems.Where(i => i.title.ToLower().Contains(searchFor.ToLower()) || string.IsNullOrEmpty(i.subText) ? 1 == 1 : i.subText.ToLower().Contains(searchFor.ToLower()));

                    var matches = _adapter.AllItems.Where(i => i.item.ToLower().Contains(searchFor.ToLower()) || (i.subItem != null && i.subItem.ToLower().Contains(searchFor.ToLower())));//   !string.IsNullOrEmpty(i.subText) ? i.subText.ToLower().Contains(searchFor.ToLower()) : null);


                    foreach (var match in matches)
                    {
                        matchList.Add(match);
                    }

                    _adapter.MatchItems = matchList;
                    Console.WriteLine("resultCount:" + matchList.Count);

                    List<FilterableListViewModel> matchObjects = new List<FilterableListViewModel>();
                    for (int i = 0; i < matchList.Count; i++)
                    {
                        matchObjects.Add(matchList[i]);
                    }

                    results.Count = matchList.Count;
                }
                else
                {
                    _adapter.ResetSearch();
                }
                return results;
            }

            protected override void PublishResults(Java.Lang.ICharSequence constraint, Filter.FilterResults results)
            {
                _adapter.NotifyDataSetChanged();
            }
        }
    }
}

FilterableListViewModel.cs:

public class FilterableListViewModel
{
   public string id { get; set; }
   public string item { get; set; }
   public string subItem { get; set; }
   public string displayName { get; set; }
}

filterList_view.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/ListView_style">
  <TextView
      android:id="@+id/list_itemContent"
      android:textColor="#000000"
      android:text="sample"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
       android:textSize="18sp"
      android:layout_marginRight="@dimen/_15sdp"
      android:layout_marginLeft="@dimen/_15sdp"
      android:paddingTop="@dimen/_4sdp" />
</LinearLayout>

活动:

   [Activity(Label = "SuburbListActivity")]
    public class SuburbListActivity : Activity
    {
        private FilterableAdapter _adapter;
        private ListView _list;
        private EditText _filterText;
        private ISuburbs suburbInfo;
        Android.App.ProgressDialog progress;
        public ILog Log { get; private set; }

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.filter_list);
            ActionBar.SetHomeButtonEnabled(true);
            ActionBar.SetDisplayHomeAsUpEnabled(true);
            ActionBar.SetDisplayOptions(ActionBarDisplayOptions.ShowCustom, ActionBarDisplayOptions.ShowCustom);
            // ActionBar.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Black));

            LayoutInflater inflater = (LayoutInflater)GetSystemService(Context.LayoutInflaterService);
            View v = inflater.Inflate(Resource.Layout.layout_actionbar_centerTitle, null);

            ActionBar.LayoutParams p = new ActionBar.LayoutParams(
                    ViewGroup.LayoutParams.MatchParent,
                    ViewGroup.LayoutParams.MatchParent,
                   GravityFlags.Center);

            var title = ((TextView)v.FindViewById(Resource.Id.title));
            title.Text = "Select Suburb";

            ActionBar.SetCustomView(v, p);
            ActionBar.SetDisplayShowTitleEnabled(true);
            ActionBar.SetDisplayHomeAsUpEnabled(true);


            progress= new Android.App.ProgressDialog(this);
            progress.SetProgressStyle(Android.App.ProgressDialogStyle.Spinner);
            progress.SetMessage(WaitMessage);
            progress.SetCancelable(false);

            progress.Show();
            InitializeComponant();
            InitializeEvents();
            BindData();

        }

        private void InitializeComponant()
        {
            suburbInfo = Dependencies.Container.Get<ISuburbs>();
            Log = Dependencies.Container.Get<ILog>();

            _list = FindViewById<ListView>(Resource.Id.filterList);
            _filterText = FindViewById<EditText>(Resource.Id.search);

        }

        /// <summary>
        /// initialize evnts
        /// </summary>
        private void InitializeEvents()
        {
            _list.ItemClick += List_ItemClick;
        }

        private void List_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            var listItem = _adapter.GetMatchedItem(e.Position);
            //var serviceRoleId = listItem.id;
            //var hasPIC = listItem.subItem;
            Intent myIntent = new Intent(this, typeof(RegisterActivity));
            myIntent.PutExtra("suburbId", listItem.id);
            myIntent.PutExtra("suburbName", listItem.item);
            myIntent.PutExtra("postcode", listItem.subItem);
            SetResult(Result.Ok, myIntent);
            Finish();
        }

        private async Task BindData()
        {

            //var serviceRoleList = await serviceInfo.GetAllAsync();
            RegistrationFacade regFacade = new RegistrationFacade(Log, null, null, suburbInfo);
            List<FilterableListViewModel> states = await regFacade.GetSuburbs();

            //List<FilterableListViewModel> testmodel = new List<FilterableListViewModel>();
            //testmodel.Add(new FilterableListViewModel { subItem = "abc, goa, panjim", id = "1", item = "abc" });
            //testmodel.Add(new FilterableListViewModel { subItem = "qwe, maha, vasco", id = "1", item = "qwe" });
            //testmodel.Add(new FilterableListViewModel { subItem = "rty, karna, panjim", id = "1", item = "rty" });
            //testmodel.Add(new FilterableListViewModel { subItem = "uio, assa, marg", id = "1", item = "ttt" });
            _adapter = new FilterableAdapter(this, Resource.Drawable.filterList_view, states);
            _list.Adapter = _adapter;

            _filterText.TextChanged += (object sender, Android.Text.TextChangedEventArgs e) =>
            {
                var searchTerm = _filterText.Text;
                if (String.IsNullOrEmpty(searchTerm))
                {
                    _adapter.ResetSearch();
                }
                else
                {
                    _adapter.Filter.InvokeFilter(searchTerm);
                }
            };

            progress.Hide();

        }
    }

关于如何修改代码以获取多选列表的任何帮助?

这是我已经拥有的:

这是我在Umair's 建议之后的适配器:

  public class FilterableMultiselectAdapter : ArrayAdapter, IFilterable
    {
        LayoutInflater inflater;
        Filter filter;
        Activity context;
        public List<FilterableListViewModel> AllItems;
        public List<FilterableListViewModel> MatchItems;

        public FilterableMultiselectAdapter(Activity context, int txtViewResourceId, List<FilterableListViewModel> items) : base(context, txtViewResourceId, items)
        {
            inflater = context.LayoutInflater;
            filter = new SuggestionsFilter(this);
            AllItems = items;
            MatchItems = items;
        }

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

        public override Java.Lang.Object GetItem(int position)
        {
            return null;
        }

        public FilterableListViewModel GetMatchedItem(int position)
        {
            return MatchItems[position];
        }


        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View view = convertView;
            if (view == null)
                view = inflater.Inflate(Resource.Drawable.filterMultiselectList_view, null);

            view.FindViewById<CheckedTextView>(Resource.Id.chkTV).Text = MatchItems[position].displayName;
            return view;
        }

        public override Filter Filter
        {
            get
            {
                return filter;
            }
        }

        public void ResetSearch()
        {
            MatchItems = AllItems;
            NotifyDataSetChanged();
        }

        class SuggestionsFilter : Filter
        {
            readonly FilterableMultiselectAdapter _adapter;

            public SuggestionsFilter(FilterableMultiselectAdapter adapter) : base()
            {
                _adapter = adapter;
            }

            protected override Filter.FilterResults PerformFiltering(Java.Lang.ICharSequence constraint)
            {
                FilterResults results = new FilterResults();
                if (!String.IsNullOrEmpty(constraint.ToString()))
                {
                    var searchFor = constraint.ToString();
                    Console.WriteLine("searchFor:" + searchFor);
                    var matchList = new List<FilterableListViewModel>();
                    //var matches = _adapter.AllItems.Where(i => i.title.ToLower().Contains(searchFor.ToLower()) || string.IsNullOrEmpty(i.subText) ? 1 == 1 : i.subText.ToLower().Contains(searchFor.ToLower()));

                    var matches = _adapter.AllItems.Where(i => i.item.ToLower().Contains(searchFor.ToLower()) || (i.subItem != null && i.subItem.ToLower().Contains(searchFor.ToLower())));//   !string.IsNullOrEmpty(i.subText) ? i.subText.ToLower().Contains(searchFor.ToLower()) : null);


                    foreach (var match in matches)
                    {
                        matchList.Add(match);
                    }

                    _adapter.MatchItems = matchList;
                    Console.WriteLine("resultCount:" + matchList.Count);

                    List<FilterableListViewModel> matchObjects = new List<FilterableListViewModel>();
                    for (int i = 0; i < matchList.Count; i++)
                    {
                        matchObjects.Add(matchList[i]);
                    }

                    results.Count = matchList.Count;
                }
                else
                {
                    _adapter.ResetSearch();
                }
                return results;
            }

            protected override void PublishResults(Java.Lang.ICharSequence constraint, Filter.FilterResults results)
            {
                _adapter.NotifyDataSetChanged();
            }
        }
    }

【问题讨论】:

  • 你到底是什么意思 multiSelect list ?你想在列表中选择多个项目吗?如果是,那么我们也可以检查TextView 而不是简单的文本视图并相应地进行处理。
  • 是的,我想在列表中选择多个项目,我还需要该列表的搜索选项。
  • 查看您附加的图片,您似乎已经实现了搜索选项,但您无法选择多个项目。
  • 在下面查看我的答案,它会让您知道如何做到这一点。

标签: android android-filterable


【解决方案1】:

您可以使用CheckedTextView 从微调器下拉列表中选择多个项目。

<?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">

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/chkTV"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableLeft="?android:attr/listChoiceIndicatorMultiple"
    android:drawableStart="?android:attr/listChoiceIndicatorMultiple"
    android:clickable="true"
    android:focusable="true"
    android:gravity="center_vertical"
    android:padding="5dp"
    android:text="@string/action_settings"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:textStyle="bold" />

 </RelativeLayout>

然后在您的适配器类的 getView 方法中执行以下操作:

viewHolder.chkTV.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.chkTV.isChecked()) {
                viewHolder.chkTV.setChecked(false);
                if (mModel != null) {
                    addItemIntoUnCheckedList(mModel.getId());
                }

            } else {
                viewHolder.chkTV.setChecked(true);
                if (mModel != null) {
                    addItemIntoCheckedList(mModel.getId());
                }
            }
        }
    });


 private void addItemIntoCheckedList(int id) {


    Model phyFac = new Model();
    phyFac.Id = ID;
    // do your model work here for the checkedItem

    if (UnCheckedByUser != null && UnCheckedByUser.size() > 0) {


        for (int i = 0; i < UnCheckedByUser.size(); i++) {
            if (UnCheckedByUser.get(i).getId() == phyFac.getId()) {
                UnCheckedByUser.remove(i);
            }
        }
    }
    checkedListOfFacilities.add(phyFac);

}

private void addItemIntoUnCheckedList(int Id) {

    Model unCheckedPhyFac = new Model();
    unCheckedPhyFac.Id = ID;
    unCheckedPhyFac.Id = Id;

    if (checkedList != null && checkedList.size() > 0) {

        for (int i = 0; i < checkedList.size(); i++) {
            if (checkedList.get(i).getId() == unCheckedPhyFac.getId()) {
                checkedList.remove(i);
            }
        }
    }

    UnCheckedByUser.add(unCheckedPhyFac);
}

现在,最后您将使用这种方法获得未选中和选中的列表,并且您可以对这些列表执行任何您想做的事情。希望对您有所帮助。

【讨论】:

  • 这没有帮助,列表没有显示出来。我试图只用 CheckedTextView 更改替换 textview 并且它没有显示
  • @Arti 你是否将这个checkedTextView 布局作为项目布局传递?
  • 是的。可能是因为可过滤吗?
  • 它不应该这样做,因为它是可过滤的。但是你能检查它是否在没有过滤器的情况下工作吗?
  • 什么是 mModel ?
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 2023-03-23
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 2017-06-14
相关资源
最近更新 更多