老师,当RecyclerView使用Diff去更新数据遇到一个问题

来源:1-1 课程概述

慕用1394343

2022-02-10

  1. 数据模型
//实现了老师的DiffUiDataCallback.UiDataDiffer
data class Main(val id: Int, val name: String) : DiffUiDataCallback.UiDataDiffer<Main> {
        override fun isSame(old: Main): Boolean {
            return this === old
        }

        override fun isUiContentSame(old: Main): Boolean {
            return this == old
        }
    }
  1. 一个简单的Adapter
class Adapter(val dataList: MutableList<Main>) : RecyclerView.Adapter<Adapter.ViewHolder>() {
        class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            val text = itemView.findViewById<TextView>(R.id.name)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val view = LayoutInflater.from(parent.context).inflate(R.layout.content_list_item, parent, false)
            return ViewHolder(view)
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            Log.d("打印这个ViewHolder"," $holder")
            holder.text.text = dataList[position].name
        }

        override fun getItemCount(): Int {
            return dataList.size
        }
    }
  1. 当新数据到来时更新
val oldList = adapter.dataList
val newList = 刷新得到的新数据
// 进行数据对比
val callback: DiffUtil.Callback = DiffUiDataCallback(oldList, newList)
val result = DiffUtil.calculateDiff(callback)

//增量更新
adapter.dataList.clear()
adapter.dataList.addAll(newList)
result.dispatchUpdatesTo(adapter)
  1. 问题
    方便测试就假设获取的数据始终只有一个,只是每次刷新来的数据name会变换,当我去刷新获取新数据并进行增量更新时,打印出会发现ViewHolder会有两个实例,使用diff进行增量刷新就有这个问题,正常的notifyDataSetChanged没有。 只大概知道RecyclerView获取缓存的问题
//看打印结果可以发现每刷新就会去从缓存中加载上一个ViewHolder,也就是在一个位置实际上创建了两个ViweHolder
打印这个ViewHolder  ViewHolder{a42e991 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
打印这个ViewHolder  ViewHolder{6c1c7c4 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
打印这个ViewHolder  ViewHolder{a42e991 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
打印这个ViewHolder  ViewHolder{6c1c7c4 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}

写回答

2回答

慕用1394343

提问者

2022-03-17

老师,面试官让说说做的某个项目,这个应该怎么去说? 我找个实习的,写过较为简单的项目,每次让介绍下,我都不知道咋去介绍好,本来项目不难,都是些基础的,感觉没啥说的🤣

0
1
Qiujuer
如果项目的确很简单,拿你可以从项目建设的一些框架上去讲,尽可能的突出你的设计想法。可能整个app并不复杂,但是你可以说你的设计思路,如何实现扩展性强、鲁棒性强,的整个架构。
2022-03-28
共1条回复

Qiujuer

2022-02-14

这里打印holder没有啥意义呀

你应该打印的是 是否有新创建holder,以及bind时候的数据信息,而不是holder的信息。holder是recycer管理的,存在复用也存在自主创建的情况,这个都是正常的。

0
3
Qiujuer
回复
慕用1394343
明白你的意思了,这个其实是不受控制的,本身属于recyclerview内部的缓存池的逻辑;一般我们的做法是在数据中存储view的关键信息,bind时根据这些值固定的设置view的状态;保证view与数据的一致性。
2022-02-22
共3条回复

手把手开发完整的即时通讯App 客户端+服务端+MVP架构

客户端+服务端+MVP架构+封装思想+主流框架

1749 学习 · 872 问题

查看课程