我想在 android Xamarin 中实现多选列表。我使用了checkedTextview
的自定义适配器。
适配器类:
public class FilterableMultiselectAdapter : ArrayAdapter, IFilterable, View.IOnClickListener
{
LayoutInflater inflater;
Filter filter;
Activity context;
public List<FilterableListViewModel> AllItems;
public List<FilterableListViewModel> MatchItems;
public List<string> SelectedItems= new List<string>();
private CheckedTextView _checkedText;
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 List<string> SelectedItemsList()
{
return SelectedItems;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = inflater.Inflate(Resource.Drawable.filterMultiselectList_view, null);
_checkedText = view.FindViewById<CheckedTextView>(Resource.Id.chkTV);
_checkedText.Text = MatchItems[position].displayName;
_checkedText.SetOnClickListener(this);
return view;
}
public void OnClick(View V)
{
if (((CheckedTextView)V).Checked)
{
// set check mark drawable and set checked property to false
// value = "un-Checked";
((CheckedTextView)V).SetCheckMarkDrawable(0);
((CheckedTextView)V).Checked = (false);
}
else
{
// set cheek mark drawable and set checked property to true
// value = "Checked";
((CheckedTextView)V).SetCheckMarkDrawable(Resource.Drawable.ic_check);
((CheckedTextView)V).Checked = (true);
addItemIntoCheckedList(((CheckedTextView)V).Text);
}
}
private void addItemIntoCheckedList(string id)
{
SelectedItems.Add(id);
}
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();
}
}
}
这里的问题是假设我的列表中有4个项目,我选择了第1个和第2个项目,然后我去搜索一些给我剩余列表的内容,然后复选框的选择无法正常工作。
我试图找出问题,但我无法解决这个问题。我在Stackoverflow上发现了一个类似的问题,但它的解决方案指向和android库。我不能使用android库,因为我正在使用Xamarin android。
如果有人已经解决了这个问题,请帮助我。
答案 0 :(得分:1)
我不是Xamarin开发人员,但我可以说你的代码没有优化。例如,您不需要使用成员变量private CheckedTextView _checkedText;
,而是使用方法范围/局部变量。您可能希望查看ViewHolder模式以优化内存使用和性能。要解决您的问题,请检查代码段中的// TODO
条评论,首先出现逻辑错误:
public void OnClick(View V)
{
if (((CheckedTextView)V).Checked)
{
// set check mark drawable and set checked property to false
// value = "un-Checked";
((CheckedTextView)V).SetCheckMarkDrawable(0);
((CheckedTextView)V).Checked = (false);
// TODO I believe you should remove your item from SelectedItems
SelectedItems.Remove(((CheckedTextView)V).Text);
}
else
{
// set cheek mark drawable and set checked property to true
// value = "Checked";
((CheckedTextView)V).SetCheckMarkDrawable(Resource.Drawable.ic_check);
((CheckedTextView)V).Checked = (true);
addItemIntoCheckedList(((CheckedTextView)V).Text);
}
}
然后在方法GetView
上,您应该检查SelectedItems
列表中是否存在您的ID /文字
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = inflater.Inflate(Resource.Drawable.filterMultiselectList_view, null);
_checkedText = view.FindViewById<CheckedTextView>(Resource.Id.chkTV);
_checkedText.Text = MatchItems[position].displayName;
_checkedText.SetOnClickListener(this);
// TODO check if the item is checked based on the id you have saved
// something like this:
if (SelectedItems.Contains(_checkedText.Text)) {
_checkedText.Checked = true;
_checkedText.SetCheckMarkDrawable(Resource.Drawable.ic_check);
}
else {
_checkedText.Checked = false;
_checkedText.SetCheckMarkDrawable(0);
}
return view;
}
答案 1 :(得分:0)
您在单独的列表SelectedItems
中管理所选项目,因此当MatchItems
更改SelectedItems
的内容变为过时而不是单独管理时,在模型中定义boolean
{ {1}} MatchItems
并更新isSelected/isChecked