Android横向RecyclerView滚动触发多选及左边距异常问题求助
横向RecyclerView单选+复用错乱问题修复方案
问题根因
- 没有适配RecyclerView的Holder复用机制:仅对position=0的条目设置了选中状态、左边距、不可点击属性,其他位置的条目复用曾经渲染过position=0的Holder时,会保留旧状态,导致出现间隔重复选中、多余左边距的问题
- 选中状态存储在View层而非数据层:静态变量存储选中的View实例,View被回收复用后引用失效,滚动后选中状态逻辑混乱
- 属性只赋值不重置:左边距、选中状态、文字颜色等属性仅在满足条件时修改,不满足时没有重置为默认值,复用后必然错乱
修复代码
首先在Adapter类中新增成员变量存储选中位置,删除原companion object中存储选中View的静态变量:
// 初始值为0,默认选中第一个条目 private var currentSelectedPos = 0
修改bind方法,所有属性按当前position状态全量赋值,避免复用错乱:
fun bind( context: Context?, name: String, position: Int ) { // 1. 统一处理左边距:仅第一个条目加左边距,其余条目重置为0 val layoutParams = cardView?.layoutParams as ViewGroup.MarginLayoutParams? layoutParams?.leftMargin = if (position == 0) 52 else 0 cardView?.layoutParams = layoutParams // 2. 统一处理选中状态、点击属性、文字颜色 val isCurrentSelected = position == currentSelectedPos cardView?.apply { isSelected = isCurrentSelected isClickable = !isCurrentSelected findViewById<TextView>(R.id.iv_tab_name).setTextColor( ContextCompat.getColor( context!!, if (isCurrentSelected) R.color.black else R.color.setting_text ) ) } // 3. 点击事件逻辑 itemView.setOnClickListener { // 已经是选中状态直接跳过 if (position == currentSelectedPos) return@setOnClickListener // 更新选中位置,刷新新旧两个条目即可,不需要全量刷新 val oldSelectedPos = currentSelectedPos currentSelectedPos = position notifyItemChanged(oldSelectedPos) notifyItemChanged(currentSelectedPos) } }
onBindViewHolder逻辑不需要修改,保持原有调用即可。
修复说明
所有View属性都根据当前position的状态做全量赋值,不管Holder之前被用来渲染过什么位置的条目,每次绑定时都会被覆盖为正确状态,从根源上避免复用错乱。用数据层的位置变量存储选中状态,比存储易被回收的View实例更稳定,滚动后也能正确渲染选中效果。
内容的提问来源于stack exchange,提问作者hodokeg
相关产品推荐
相关产品推荐

