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)
}
}
我反向迭代,因此在您迭代和移除项目时移除的索引是稳定的。
我刚刚看到这个示例 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)
}
}
我反向迭代,因此在您迭代和移除项目时移除的索引是稳定的。