单刷RecycleView的子Item
除非必要,应该尽可能避免调用notifyDataSetChanged()
去刷新RecyclerView
列表 ,这会对性能造成影响,所以RecyclerView.Adapter
还提供了一下几个方法:
private fun recycleViewRelated() {
mAdapter.notifyItemChanged()
mAdapter.notifyItemRangeChanged()
mAdapter.notifyItemInserted()
mAdapter.notifyItemRangeInserted()
mAdapter.notifyItemRangeRemoved()
mAdapter.notifyItemRemoved()
}
notifyItemXXXChanged()
:通知指定索引的item调用onBindViewHolder()
刷新界面
notifyItemXXXInserted()
:通知在指定索引处插入item,即插入ViewHolder,有可能复用,有可能重新调用onCreateViewHolder()
创建
notifyItemXXXRemoved()
: 通知移除指定索引的item,即移除ViewHolder,并根据情况放到大家了解的1级mAttachedScrap
缓存或3级缓存RecycledViewPool
中
上面的几个情况大家根据情况调用,请注意调用上面单刷方法时,同样要保证RecyclerView
数据源也进行了插入/删除/更新操作
,否则可能会引发不必要的异常。
单刷RecycleView的子Item的局部内容
有时候,某个子Item对应的布局比较复杂,且每次刷新只可能会刷新其中一部分,这个时候使用上面介绍的单刷就会刷新到子item中不必要刷新的部分,这个时候我们可以借助payload
实现单刷Item中的某一部分内容。
接下来介绍两种方式,假设当前Item布局如下,当前只想刷新顶部内容
:
1.普通payload方式
这个主要是借助带payload
参数的notifyItemXXXRemoved/Changed/Inserted()
方法+带payloads
参数的onBindViewHolder()
方法实现,接下来我们来看代码实操。
我们用1、2、3分别来标识Item的顶部、中部和底部对应布局内容,目前我们只想刷新标识为1对应的顶部内容:
mAdapter.notifyItemChanged(0, 1)
上面代码就代表着刷新下标为0对应item布局的顶部内容,接下来我们在onBindViewHolder()
中处理:
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int,
payloads: MutableList<Any>
) {
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
return
}
when(payloads[0]) {
//刷新顶部内容
1 -> {}
//刷新中部内容
2 -> {}
//刷新底部内容
3 -> {}
}
}
得用带有如上payloads
参数的onBindViewHolder()
才能处理通过notifyItemChanged()
最后一个参数传递过来的payload
参数。
请注意当payloads
集合参数为空时,要主动调用super.onBindViewHolder(holder, position, payloads)
保证单item的整体刷新。
2.ListAdapter方式
ListAdapter
是基于DiffUtil
实现列表中部分item刷新的,具体的使用这里不做过多介绍。
当我们继承ListAdapter
自定义一个适配器时,要传入一个DiffUtil.ItemCallback
对象,这个对象有个getChangePayload()
方法,这里就是实现item中局部内容刷新的关键。
private class InnerAdapter2 : ListAdapter<String, RecyclerView.ViewHolder>(object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
}
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
}
override fun getChangePayload(oldItem: String, newItem: String): Any? {
return super.getChangePayload(oldItem, newItem)
}
})
我们只需要对上面的getChangePayload()
方法重写,根据数据变更的范围来决定刷新item的顶部、中部还是底部。
override fun getChangePayload(oldItem: String, newItem: String): Any? {
val list = mu
//如果数据变更会影响item顶部内容显示,则返回1刷新item顶部内容
if (oldItem != newItem) {
return 1
}
//如果数据变更会影响item顶部内容显示,则返回2刷新item中部内容
if (oldItem != newItem) {
return 2
}
//如果数据变更会影响item顶部内容显示,则返回3刷新item底部内容
if (oldItem != newItem) {
return 3
}
return super.getChangePayload(oldItem, newItem)
}
接下来我们在onBindViewHolder
中处理就行 ,处理的方式和上面相同,这里就再描述。
如果我们想要同时实现item中顶部和底部布局内容的同时刷新,那就可以向onBindViewHolder()
的payload中传一个集合包含1和3标识或者其他特殊标识等等,方式不限,只要能让onBindViewHolder()
知道要刷新顶部和底部就即可。
总结
本篇文章主要是讲解了如何实现RecyclerView
中子item如何单独刷新以及子item的某一部分内容如何实现单独刷新,没什么难度,大家知道并学会运用即可,更多关于Android RecyclerView单独刷新的资料请关注编程网其它相关文章!