如何每隔5秒更新ViewPager2数据,解决notifyDataSetChanged后页面显示错误问题
问题根因分析
- Adapter全局持有Binding实例是核心错误:你把
HolderTestBinding定义成了Adapter的全局变量,每次调用onCreateViewHolder创建新ViewHolder时都会覆盖这个全局binding实例,最终所有ViewHolder调用bind方法时,操作的都是最后一个创建的item的binding,自然会出现文字串位、显示错误的问题。 - 全量调用
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
相关产品推荐
相关产品推荐

