如何避免新增条目时RecyclerView的onBindViewHolder遍历全部列表项
问题根源
你当前的性能问题完全来自addMessage方法中调用的notifyDataSetChanged():这个API会通知RecyclerView「整个数据集已经全部失效」,触发全量重绘逻辑,所有当前可见的列表项都会重新执行onBindViewHolder,这就是你看到的每次加新消息都会遍历所有历史消息的原因。
你之前加的position判断属于错误的规避方案,会导致旧消息滑出屏幕再滑入时没有绑定数据,出现内容错乱、空白等问题,必须删掉。
你提到的论坛帖子和你遇到的是完全相同的问题,核心错误点都是误用了全量刷新API。
修复方案
把全量刷新替换为增量刷新API即可,你每次都是在消息列表末尾追加新消息,只需要通知RecyclerView指定位置有新条目插入,就只会触发新条目的onBindViewHolder,不会影响已有消息。
修改后的addMessage代码如下:
// boolean sent: false = received, true = sent public void addMessage (boolean sent, String msgContent) { messages.add(new MessageItem(sent, msgContent)); // 替换原来的notifyDataSetChanged(),通知末尾位置有新条目插入 notifyItemInserted(messages.size() - 1); }
同时把onBindViewHolder中的position判断删除,恢复你最初的完整绑定逻辑即可。
额外优化建议
如果你的聊天列表默认要展示最新的底部消息,可以给RecyclerView添加如下配置,新增消息后会自动滚动到底部,无需额外编写滚动逻辑:
LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setStackFromEnd(true); recyclerView.setLayoutManager(layoutManager);
内容的提问来源于stack exchange,提问作者Arvin Akhavan
相关产品推荐
相关产品推荐

