You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android RecyclerView点击item时偶现小幅异常滚动问题求助

问题原因
  1. 调用notifyItemChanged()刷新选中/取消选中条目时,RecyclerView默认的DefaultItemAnimator会执行条目变更动画,动画过程中触发条目重新布局,导致列表出现小幅滚动。
  2. 当前刷新逻辑为全量重新绑定整个条目,即使仅背景需要更新,冗余的绑定逻辑也可能加剧布局抖动。
  3. 若未给RecyclerView开启setHasFixedSize(true),条目变更时会触发整表重新测量,也会产生滚动偏移。
解决方案

方案1:使用Payload局部刷新(推荐)

仅更新条目背景,不触发全量绑定,从根源避免布局抖动:

  1. 修改ViewHolder点击事件中的刷新逻辑,携带Payload标记仅更新选中状态:
binding.root.setOnClickListener{
    val position = bindingAdapterPosition
    if (position != RecyclerView.NO_POSITION){
        val item = getItem(position)
        if (item != null){
            listener.onItemClick(item, position)
        }
        // 用已经校验过的position,不要用absoluteAdapterPosition
        notifyItemChanged(selectedItemPosition, "UPDATE_SELECTION")
        selectedItemPosition = position
        notifyItemChanged(selectedItemPosition, "UPDATE_SELECTION")
    }
}
  1. 重写三参数的onBindViewHolder,处理Payload局部更新:
override fun onBindViewHolder(holder: PolozkaViewHolder, position: Int, payloads: MutableList<Any>) {
    // 仅更新选中状态的场景
    if (payloads.isNotEmpty() && payloads.contains("UPDATE_SELECTION")) {
        if (selectedItemPosition == position){
            holder.itemView.setBackgroundColor(Color.parseColor("#DA745A"))
        } else {
            holder.itemView.setBackgroundColor(Color.TRANSPARENT)
        }
        return
    }
    // 其他场景走原有全量绑定逻辑
    super.onBindViewHolder(holder, position, payloads)
}

方案2:关闭条目变更动画

如果不需要条目切换动画,可以直接关闭动画效果:

// 仅关闭change动画
(recyclerView.itemAnimator as? DefaultItemAnimator)?.supportsChangeAnimations = false
// 或者完全关闭所有item动画
recyclerView.itemAnimator = null

方案3:补充基础配置

给RecyclerView开启固定尺寸优化,避免不必要的整表测量:

recyclerView.setHasFixedSize(true)

同时给条目布局根节点设置固定高度,避免文字换行等场景导致的条目高度变更。


内容的提问来源于stack exchange,提问作者jenik2205

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:24:04