如何解决RecyclerView.Adapter修改item gravity时非目标项属性错乱问题
问题根因
该问题由RecyclerView的ViewHolder复用机制导致:
- RecyclerView不会为每一个列表条目创建独立的View实例,当列表滚动、原有条目滑出屏幕后,对应的ViewHolder对象会被回收到缓存池,直接复用来渲染新滑入屏幕的条目。
- 你的代码仅在
position == 0时给TextView设置了特殊gravity值,但这个ViewHolder被回收复用到其他位置(比如日志中的position=9)时,你没有将gravity属性重置为非首项的默认值,之前给首项设置的gravity就被残留保留,最终导致非首项也出现了异常的gravity效果。
从运行日志可以直接印证这个结论:你仅在position == 0时打印了position -> 0的标记日志,但position=9的gravity值和position=0的8388627完全一致,说明这个ViewHolder之前确实绑定过首项,被复用后没有重置属性。
修复方法
修改onBindViewHolder中的逻辑,对所有位置都显式设置对应要求的gravity值,不要依赖View的初始属性,避免复用残留的旧值影响显示:
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { viewHolder.textView.text = dataSet[position] if (position == 0) { Log.i("Position", " position -> $position ") // 首项设置指定gravity viewHolder.textView.gravity = Gravity.START or Gravity.CENTER_VERTICAL } else { // 非首项必须显式重置为默认gravity(从日志看默认值17对应Gravity.CENTER,和你布局定义保持一致即可) viewHolder.textView.gravity = Gravity.CENTER } Log.i("Position", " gravity -> $position " + viewHolder.textView.gravity) }
注意事项
所有在onBindViewHolder中动态修改的View属性,都必须做全分支赋值:只要你给特定位置设置了特殊属性,就一定要在其他分支下显式把属性改回默认值,不能只改特殊场景、不处理普通场景的重置,否则只要ViewHolder发生复用,就会出现属性串改的问题。
内容的提问来源于stack exchange,提问作者Arthurghev
相关产品推荐
相关产品推荐

