Android中EditText过滤ListView不更新问题求助
问题:Android中EditText过滤ListView不更新显示
我在Android中使用EditText过滤ListView组件,在TextWatcher的afterTextChanged方法中执行了如下代码:
cardBoxListViewAdapter.getFilter().filter(editable);
自定义Adapter代码如下:
public class CardBoxListViewAdapter extends ArrayAdapter<CardBoxItems> implements Filterable { private static final String TAG = "CardBoxListAdapter"; private ValueFilter valueFilter; ArrayList<CardBoxItems> cardBoxModelArrayList; ArrayList<CardBoxItems> cardBoxModelArrayList2; private Context context; public CardBoxListViewAdapter(Context context, ArrayList<CardBoxItems> cardBoxModelArrayList) { super(context, 0, cardBoxModelArrayList); this.cardBoxModelArrayList = cardBoxModelArrayList; this.cardBoxModelArrayList2 = cardBoxModelArrayList; this.context = context; getFilter(); } @Override public View getView(int position, View view, ViewGroup parent) { final CardBoxItems cardBoxModel = getItem(position); if (view == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_listview_cardbox, parent, false); } TextView searchedFor = view.findViewById(R.id.cardBoxTitle); String searchedForString = cardBoxModel.getSearchedFor().replace("+", " "); searchedFor.setText(searchedForString); return view; } @Override public Filter getFilter() { if (valueFilter == null) { valueFilter = new ValueFilter(); } return valueFilter; } private class ValueFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence charSequence) { FilterResults results = new FilterResults(); if (charSequence != null && charSequence.length() > 0) { ArrayList<CardBoxItems> filteredList = new ArrayList<>(); for (int i = 0; i < cardBoxModelArrayList.size(); i++) { if (cardBoxModelArrayList.get(i).getSearchedFor().toLowerCase().contains(charSequence.toString().toLowerCase())) { filteredList.add(cardBoxModelArrayList.get(i)); } } results.count = filteredList.size(); results.values = filteredList; } else { results.count = cardBoxModelArrayList.size(); results.values = cardBoxModelArrayList; } return results; } @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) { cardBoxModelArrayList2 = (ArrayList<CardBoxItems>) filterResults.values; System.out.println(cardBoxModelArrayList2.size()); notifyDataSetChanged(); } } }
当前问题:控制台打印的列表长度正确,但ListView本身没有更新显示。已创建第二个ArrayList存储过滤后的信息,但问题仍未解决。
问题排查与解决方案
核心问题
你继承了ArrayAdapter,但过滤后仅更新了自定义的cardBoxModelArrayList2,而getView中调用的getItem(position)是从ArrayAdapter内部维护的数据源获取数据,并未同步更新;同时getCount方法默认返回ArrayAdapter数据源的大小,导致ListView无法感知过滤后的集合长度变化。
修复步骤
区分原始数据与过滤数据的引用
构造方法中直接赋值会导致多个变量指向同一个集合,需创建集合副本:public CardBoxListViewAdapter(Context context, ArrayList<CardBoxItems> cardBoxModelArrayList) { super(context, 0, new ArrayList<>(cardBoxModelArrayList)); this.cardBoxModelArrayList = new ArrayList<>(cardBoxModelArrayList); // 保存原始完整数据 this.cardBoxModelArrayList2 = new ArrayList<>(cardBoxModelArrayList); // 初始化过滤数据 this.context = context; }修改
getView从过滤集合取数据
替换getItem(position)为自定义过滤集合的获取方式:@Override public View getView(int position, View view, ViewGroup parent) { final CardBoxItems cardBoxModel = cardBoxModelArrayList2.get(position); // 从过滤后的集合取数据 if (view == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_listview_cardbox, parent, false); } TextView searchedFor = view.findViewById(R.id.cardBoxTitle); String searchedForString = cardBoxModel.getSearchedFor().replace("+", " "); searchedFor.setText(searchedForString); return view; }重写
getCount方法返回过滤集合大小
让ListView知道当前要显示的项数:@Override public int getCount() { return cardBoxModelArrayList2.size(); }可选:重写
getItem方法(若有其他地方调用)
如果代码中有其他地方调用getItem,也需要同步修改:@Override public CardBoxItems getItem(int position) { return cardBoxModelArrayList2.get(position); }
完成以上修改后,过滤操作会正确更新ListView的显示内容,因为现在Adapter的数据源完全由你维护的cardBoxModelArrayList2控制,notifyDataSetChanged会触发ListView重新加载数据。
内容的提问来源于stack exchange,提问作者newPHPDev
相关产品推荐
相关产品推荐

