EditText筛选演员列表报错及筛选无效问题求助
看起来你遇到的问题主要来自两个核心点:ArrayAdapter默认筛选逻辑不匹配你的需求,以及代码里的小语法/逻辑问题。咱们一步步拆解解决:
1. 为什么直接调用itemsAdapter.getFilter().filter(charSequence)没效果?
ArrayAdapter的默认Filter是通过调用每个item的toString()方法来匹配筛选文本的,但你的Actor类没有重写toString(),所以默认使用的是Object类的toString()——返回的是类似com.example.aylin.movieapp.Actor@xxxxxx的类哈希字符串,自然和你输入的演员名字完全匹配不上。
快速修复:重写Actor类的toString()
修改你的Actor类,让它返回你想要用来筛选的字段(比如演员名字mActor):
public class Actor { // 你的现有属性、构造方法、getter方法保持不变... @Override public String toString() { // 返回要用于筛选的核心字段,这里选择演员名字 return mActor; } }
如果需要同时支持名字和人气的模糊筛选,也可以返回拼接后的内容:
@Override public String toString() { return mActor + " " + mPopularity; }
2. 为什么(Actors.this).itemsAdapter.getFilter().filter(charSequence)会报错?
itemsAdapter是你在onCreate里定义的final局部变量,在TextWatcher这个内部类里可以直接访问,不需要额外加Actors.this(就算加也应该是Actors.this.itemsAdapter,但完全没必要)。修正后的onTextChanged方法应该是:
@Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { itemsAdapter.getFilter().filter(charSequence); }
3. 顺手修正一个界面显示小bug
看你的MovieAdapter的getView方法,文本显示搞反了:
// 原错误代码 songTextView.setText((currentWord.getmPopularity())); singerTextView.setText(currentWord.getmActor());
根据变量名推测,应该是名字显示在songTextView,人气显示在singerTextView,修正后:
songTextView.setText(currentWord.getmActor()); singerTextView.setText(currentWord.getmPopularity());
这个不影响筛选,但会导致界面显示错乱,顺手修正更稳妥。
进阶方案:自定义Filter(复杂筛选需求)
如果默认的toString()筛选满足不了你的需求(比如需要精确匹配、多字段组合筛选、大小写不敏感匹配等),可以在MovieAdapter里自定义Filter,灵活性更高:
public class MovieAdapter extends ArrayAdapter<Actor> { private ArrayList<Actor> originalActorList; private ArrayList<Actor> filteredActorList; public MovieAdapter(Activity context, ArrayList<Actor> words) { super(context, 0, words); originalActorList = new ArrayList<>(words); filteredActorList = new ArrayList<>(words); } // 你的getView方法保持不变... @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); ArrayList<Actor> tempFilteredList = new ArrayList<>(); if (constraint == null || constraint.length() == 0) { // 无筛选条件,返回全部数据 tempFilteredList.addAll(originalActorList); } else { String filterKeyword = constraint.toString().toLowerCase().trim(); // 遍历原列表,匹配演员名字(可扩展到匹配人气等其他字段) for (Actor actor : originalActorList) { if (actor.getmActor().toLowerCase().contains(filterKeyword)) { tempFilteredList.add(actor); } } } results.values = tempFilteredList; results.count = tempFilteredList.size(); return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { filteredActorList.clear(); filteredActorList.addAll((ArrayList<Actor>) results.values); notifyDataSetChanged(); } }; } }
按照上面的步骤修改后,你的搜索筛选功能应该就能正常工作了!
内容的提问来源于stack exchange,提问作者Aylin Görgün

