0

我有数据源(在那个例子中它只是一个 var myState: List)

class MainActivity : AppCompatActivity() {
    var generation: Int = 0
    var myState: List<User> = emptyList()
    val userAdapter = UserAdapter {
        val index = myState.indexOf(it)
        if (index == -1)
            println(" not found")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val recycler = findViewById<RecyclerView>(R.id.rvContent)
        recycler.layoutManager = LinearLayoutManager(this)
        recycler.adapter = userAdapter
        Thread {
            while (true) {
                generateNewData()
                Handler(mainLooper).post {
                    userAdapter.submit(myState)
                }
                sleep(3000L)
            }
        }.start()

    }

    fun generateNewData() {
        generation++
        myState = (0..5000).map { User("$generation", it) }
    }
}

我有 RecyclerView 和 AsyncListDiffer 连接到它

data class User(val name: String, val id: Int) {
    val createdTime = System.currentTimeMillis()
}

data class UserViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
    fun bindTo(user: User, action: (User) -> Unit) {
        val textView = view.findViewById<TextView>(R.id.title)
        textView.text = "${user.name} ${user.id} ${user.createdTime}"
        textView.setOnClickListener { action(user) }
    }
}

class UserAdapter(val action: (User) -> Unit) : RecyclerView.Adapter<UserViewHolder>() {
    val differ: AsyncListDiffer<User> = AsyncListDiffer(this, DIFF_CALLBACK);

    object DIFF_CALLBACK : DiffUtil.ItemCallback<User>() {

        override fun areItemsTheSame(oldItem: User, newItem: User): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
            return oldItem == newItem
        }

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        return UserViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false))
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = differ.currentList[position]
        holder.bindTo(user, action = action)
    }

    fun submit(list: List<User>) {
        differ.submitList(list)
    }

    override fun getItemCount(): Int {
        return differ.currentList.size
    }
}

我将 OnClickListener 绑定到 RecyclerView 上的每个项目

{
    val index = myState.indexOf(it)
    if (index == -1)
        println(" not found")}

该侦听器检查单击的项目是否存在于数据源中,如果不存在,则将其输出到控制台。每隔几秒钟,源中的数据就会发生变化,并通过 submitList 方法推送到 AsyncListDiffer,在某些情况下,它在内部使用其他线程匹配数据并将差异数据传递给 RecyclerView,这需要一些时间;如果我开始不停地单击项目,并且当差异插入新数据时同时发生单击事件,那么我将进入不一致状态。

那么,如何处理呢?

  1. 忽略数据不一致的点击?(缺点:用户可以看到一些奇怪的行为,如列表项没有折叠/展开,没有导航发生等)
  2. 尝试通过单独的字段(位置/等)在新数据中找到类似的项目,并使用它?(缺点:与1相同。但概率较小)
  3. 阻止 OnClickListener 事件,直到 Recycler 和数据源中的数据一致?(缺点:与上述相同,并且还滞后于用户执行的操作,直到数据再次变得一致)
  4. 还有什么?解决这个问题的最佳方法是什么?
4

0 回答 0