如何移除RecyclerView中TMDB返回的空白季数据项,避免多空项时崩溃?
崩溃原因
- 你在
onBindViewHolder中直接修改数据源删除元素,但没有同步通知RecyclerView数据源变更,导致RecyclerView仍持有旧的索引计数,多个空白季时很容易触发数组下标越界异常 - 你删除元素后没有中断当前绑定逻辑,后续代码依然会操作已被删除的条目对应数据,逻辑完全错位
正确解决方案
最优方案:数据源传给适配器前提前过滤(推荐)
在拿到TMDB接口返回的季列表后,先过滤掉无效条目再传给适配器,从根源避免无效数据进入适配器逻辑:
// 原始接口返回的季列表 List<Season> originSeasonList = ...; // 过滤出集数大于0的有效季 List<Season> validSeasonList = new ArrayList<>(); for (Season season : originSeasonList) { if (season.getSeasonEpisodes() > 0) { validSeasonList.add(season); } } // 用过滤后的列表初始化适配器 SeasonAdapter adapter = new SeasonAdapter(validSeasonList, context);
同时删除你原来写在onBindViewHolder中的删除逻辑即可。
备选方案:适配器构造时内部过滤
如果不方便在传入前处理,也可以在适配器构造方法中直接完成过滤,修改你的适配器构造代码:
public SeasonAdapter(List<Season> seasons, Context context) { // 内部先过滤无效数据 List<Season> validSeasons = new ArrayList<>(); for (Season season : seasons) { if (season.getSeasonEpisodes() > 0) { validSeasons.add(season); } } this.seasons = validSeasons; this.context = context; requestOptions = new RequestOptions().centerCrop().placeholder(R.drawable.poster_placeholder).error(R.drawable.poster_placeholder); }
同样删除onBindViewHolder中的原有删除逻辑即可。
不推荐的动态修复方案(仅作参考)
如果确实需要在绑定阶段动态删除,修改你的删除逻辑为如下代码,但是该方案性能差且容易触发其他问题,优先用前两种方案:
if (season.getSeasonEpisodes() == 0) { seasons.remove(position); // 通知适配器该位置条目被删除,刷新后续条目索引 notifyItemRemoved(position); notifyItemRangeChanged(position, seasons.size()); // 中断后续绑定逻辑 return; }
内容的提问来源于stack exchange,提问作者Meggan Sam
相关产品推荐
相关产品推荐

