notifyItemChanged与findViewHolderForAdapterPosition性能对比:RecyclerView进度更新方案选型
从性能与稳定性角度对比两种RecyclerView进度更新方案
咱们先从性能、稳定性、可维护性三个维度拆解这两个方案的优劣,帮你做出更合理的选择:
方案一:直接通过findViewHolderForAdapterPosition更新ProgressBar
这个方案的核心是跳过Adapter绑定流程,直接拿到对应position的ViewHolder操作UI:
@Override public void onProgressUpdate(String id, int pos, int progress) { MyViewHolder vh = recyclerView.findViewHolderForAdapterPosition(pos); vh.progressBar.setProgress(progress); }
优缺点分析:
- 看似的优势:单次更新的理论开销更小,不用走
onBindViewHolder流程,直接操作View。 - 致命问题:
- 空指针风险:当item滑出屏幕时,
findViewHolderForAdapterPosition会返回null,此时调用vh.progressBar直接崩溃。 - UI错乱风险:RecyclerView的ViewHolder是复用机制,若更新时列表正在滚动,这个position对应的ViewHolder可能已被复用给其他条目,你会错误更新无关item的进度条。
- 违背设计规范:绕开Adapter的数据源管理逻辑,代码耦合度高,后续维护成本极高。
- 空指针风险:当item滑出屏幕时,
方案二:通过HashMap存储进度,调用notifyItemChanged
这个方案遵循RecyclerView设计模式,用HashMap作为补充数据源,通过通知Adapter更新同步UI:
// Activity中的回调 @Override public void onProgressUpdate(String id, int pos, int progress) { adapter.getProgressHashmap().put(id, progress); adapter.notifyItemChanged(pos); } // Adapter中的onBindViewHolder if (progressHashmap.containsKey(id)) { int progress = progressHashmap.get(id); holder.progressBar.setProgress(progress); }
优缺点分析:
- 核心优势:
- 稳定性拉满:无论item是否在屏幕内,进度数据都存在HashMap中,当item滑回屏幕时,
onBindViewHolder会自动用最新进度更新UI,不会出现错乱或空指针。 - 符合设计规范:数据源(HashMap)与UI绑定分离,代码结构清晰,后续扩展或维护都很方便。
- 性能开销可忽略:
notifyItemChanged只会触发对应position的onBindViewHolder,RecyclerView内部做了优化,不会刷新整个列表,这点额外的方法调用开销在实际场景中完全感知不到。
- 稳定性拉满:无论item是否在屏幕内,进度数据都存在HashMap中,当item滑回屏幕时,
- 唯一小缺点:相比方案一多了一次
onBindViewHolder调用,但这点代价换来了稳定性和可维护性,完全值得。
最终结论
从性能+稳定性的综合角度来看,方案二更优。方案一的所谓“性能优势”建立在极高的崩溃和UI错乱风险之上,实际开发中绝对不推荐;而方案二的性能开销完全在可接受范围内,同时保证了代码的健壮性和可维护性,是符合RecyclerView设计理念的正确做法。
内容的提问来源于stack exchange,提问作者3llomi
相关产品推荐
相关产品推荐

