recyclerview adapter怎么知道调用onCreateViewHolder呢?

How does the recyclerview adapter know to call onCreateViewHolder?

我刚刚看到这个示例 class 用于 Recyclerview 的适配器,我有点困惑它如何知道仅通过将 Item 对象添加到列表来调用 onCreateViewHolder、onBindViewHolder 等? 它与行 notifyItemInserted(items.size - 1) 有什么关系吗? 是每当调用此方法时,都会为该项目调用 onCreateViewHolder 方法,还是? 适配器:

class ListAdapter (
    private val items: MutableList<Item>
) : RecyclerView.Adapter <ListAdapter.ListViewHolder>() {

    class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

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

    override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
        val currItem = items[position]

        holder.itemView.apply {
            tv_item.text = currItem.title
            cb_item.isChecked = currItem.checked

            crossItem(tv_item, currItem.checked)

            cb_item.setOnCheckedChangeListener { _, isChecked ->
                crossItem(tv_item, isChecked)

                currItem.checked = !currItem.checked

                items.removeAll { item ->
                    item.checked
                }
                notifyDataSetChanged()
            }
        }
    }

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

    private fun crossItem (itemText: TextView, checked: Boolean) {

        if (checked){
            //dk wtf paint flags is
            itemText.paintFlags = itemText.paintFlags or STRIKE_THRU_TEXT_FLAG
        }
        //else remove
        else {
            itemText.paintFlags = itemText.paintFlags and STRIKE_THRU_TEXT_FLAG.inv()
        }
    }

    fun addItem (item: Item){

        items.add (item)

        notifyItemInserted(items.size - 1)
    }

}

项目Class:

data class Item (
    val title: String,
    var checked: Boolean = false
)
{
}
override fun getItemCount(): Int {
    return items.size
}

这个函数是关键,它通过知道总共有多少来知道创建多少,绑定多少。创建的 ViewHolder 的数量更多取决于屏幕上一次可以容纳多少 View

当您有不同的视图类型时,这会变得更加复杂,因为随着视图类型的变化,它有时必须创建比从一开始就需要的更多的 ViewHolder

notify... functions 只是让 Adapter 知道它需要“重新查看”List

每当 Adapter 需要为 RecyclerView 提供新视图进行绘制时,它会检查其池中是否有未使用的 ViewHolder。如果没有,它会调用 onCreateViewHolder() 以便它可以创建一个。然后它为来自任一来源的 ViewHolder 调用 onBindViewHolder(),以便可以在将包含的视图添加到布局之前准备好包含的视图。

如果您调用 notify 方法之一,则会触发它刷新受影响的项目行。它会将 return 任何已删除的行添加到 ViewHolder 池中,然后按照上述步骤获取新行所需的视图。如果您使用 notify...changed 方法,则只需要对适用的行使用 onBindViewHolder()。当您使用核选项 notifyDataSetChanged() 时,它 return 将所有项目都添加到池中。

当 RecyclerView 首次显示时,或布局调整大小时,这些操作可能会触发显示更多行的需要。当您滚动列表时,滚动出屏幕的项目 return 进入 ViewHolder 池,当新项目滚动到视图中时,需要创建或从池中获取 ViewHolder,如上所述。

顺便说一句,这看起来很难看,因为即使只删除了一些项目,它也会刷新整个列表:

items.removeAll { item ->
    item.checked
}
notifyDataSetChanged()

我建议改用这个,这样您就可以顺利过渡:

for (i in items.indices.reversed()) {
    if (items[i].checked) {
        items.removeAt(i)
        notifyItemRemoved(i)
    }
}

我反向迭代,因此在您迭代和移除项目时移除的索引是稳定的。