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

如何每隔5秒更新ViewPager2数据,解决notifyDataSetChanged后页面显示错误问题

问题根因分析
  1. Adapter全局持有Binding实例是核心错误:你把HolderTestBinding定义成了Adapter的全局变量,每次调用onCreateViewHolder创建新ViewHolder时都会覆盖这个全局binding实例,最终所有ViewHolder调用bind方法时,操作的都是最后一个创建的item的binding,自然会出现文字串位、显示错误的问题。
  2. 全量调用notifyDataSetChanged没有稳定的item id标记,RecyclerView无法正确识别复用Holder,会放大显示异常的问题。
修复方案

1. 把Binding放到ViewHolder内部持有

修改Adapter代码,每个ViewHolder单独持有自己的binding实例,不要全局存储:

class ViewPagerAdapter(var list: List<TestDataObject>) : RecyclerView.Adapter<ViewPagerAdapter.TestHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.holder_test, parent, false)
        // 每个ViewHolder的binding单独创建,不共用全局实例
        val binding = DataBindingUtil.bind<HolderTestBinding>(view)!!
        return TestHolder(view, binding)
    }

    override fun onBindViewHolder(holder: TestHolder, position: Int) {
        holder.bind(list[position])
    }

    override fun getItemCount(): Int = list.size

    // 可选优化:添加稳定id,提升RecyclerView复用效率
    override fun getItemId(position: Int): Long {
        // 实际场景可替换为数据的唯一id
        return list[position].hashCode().toLong()
    }

    fun updateData(items: List<TestDataObject>) {
        list = items
        notifyDataSetChanged()
        // 后续可进一步优化为DiffUtil局部刷新,减少不必要的全局重绘
        /*val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
            override fun getOldListSize(): Int = list.size
            override fun getNewListSize(): Int = items.size
            override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                return list[oldItemPosition].titleText == items[newItemPosition].titleText
            }
            override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                return list[oldItemPosition] == items[newItemPosition]
            }
        })
        list = items
        diffResult.dispatchUpdatesTo(this)*/
    }

    inner class TestHolder(containerView: View, private val binding: HolderTestBinding) : RecyclerView.ViewHolder(containerView) {
        fun bind(testDataObject: TestDataObject) {
            binding.apply {
                titleTv.text = testDataObject.titleText
                textTv.text = testDataObject.infoText
                // 配合DataBinding使用时添加,避免刷新延迟
                executePendingBindings()
            }
        }
    }
}

2. 可选优化:开启稳定ID

初始化Adapter后添加以下代码,进一步提升RecyclerView刷新稳定性:

adapter?.setHasStableIds(true)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:57:05