Android 8.0 Oreo下ListView搜索时隐藏指定重复项问题求助
解决Android 8.0中ListView过滤时重复条目显示的问题
我明白你遇到的困扰了——正常状态下能隐藏重复的"Old High Court Interchange"条目,但一用搜索过滤功能,Android 8.0上两个重复条目就都会显示出来,其他系统却没这个问题。核心问题出在你依赖的全局flag变量上,结合Android 8.0的View回收机制,导致过滤时的判断逻辑失效了。
问题根源分析
你当前的逻辑靠一个全局flag控制是否隐藏条目,但当使用Filter搜索时,ListView会重新遍历数据集并反复调用getView方法。这时候flag的状态已经不是初始的true了,而且Android 8.0的View复用逻辑可能让不同位置的条目复用之前的View状态,导致判断混乱,最终两个重复条目都显示了出来。
解决方案
方案1:从数据集层面去重(推荐)
最稳妥的方式是在数据源头就去掉重复条目,不管是正常显示还是过滤后,数据本身就没有重复,从根源解决问题。你可以在初始化原始列表或者过滤后的列表时做去重处理:
// 示例:给Adapter设置数据前先去重 List<Station> uniqueList = new ArrayList<>(); boolean hasOldHighCourt = false; for (Station station : stationlist) { String stationName = station.getStation_name(); if ("Old High Court Interchange".equals(stationName)) { if (!hasOldHighCourt) { uniqueList.add(station); hasOldHighCourt = true; } } else { uniqueList.add(station); } } // 更新Adapter数据并刷新 yourAdapter.setData(uniqueList); yourAdapter.notifyDataSetChanged();
方案2:在getView中基于当前数据集判断(适合保留原数据集的场景)
如果必须保留原始数据集,那不要用全局flag,而是在getView里根据当前位置的条目在数据集中的出现次数来判断,只显示第一个出现的条目:
@Override public View getView(int position, View convertView, ViewGroup parent) { // 初始化ViewHolder等常规代码... Station currentStation = stationlist.get(position); String name = currentStation.getStation_name(); if ("Old High Court Interchange".equals(name)) { // 统计到当前位置为止,该名称出现的次数 int occurrenceCount = 0; for (int i = 0; i <= position; i++) { if (name.equals(stationlist.get(i).getStation_name())) { occurrenceCount++; } } // 只显示第一个,后续的都隐藏 holder.mainll.setVisibility(occurrenceCount > 1 ? View.GONE : View.VISIBLE); } else { holder.mainll.setVisibility(View.VISIBLE); } // 其他数据绑定逻辑... return convertView; }
这两种方法都能避开全局变量带来的状态混乱问题,适配包括Android 8.0在内的所有系统版本。
内容的提问来源于stack exchange,提问作者Dharmesh Patel
相关产品推荐
相关产品推荐

