嵌套recyclerView动态数据一致性
Nested recyclerView dynamic data consistency
我有垂直的 recyclerView 和几个嵌套的水平 recyclerView。每个嵌套列表通过 DiffUtils 机制动态更新。
当我更新嵌套列表时,我等待滚动保持在相同位置并且新项目出现在它的右侧,但滚动之前在页面上进行。怎么回事?
class Adapter : RecyclerView.Adapter {
private var nestedItems: List<Item> = emptyList()
fun updateNestedList(items: List<Item>) {
val diff = DiffUtil.calculateDiff(...)
nestedItems = items
diff.dispatchUpdatesTo(this)
}
override fun onCreateViewHolder() {
when (itemType) {
...
ITEM_TYPE_HORIZONTAL -> NestedListViewHolder()
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
...
is NestedListViewHolder -> (holder as NestedListViewHolder).bind(items)
}
}
}
class NestedListViewHolder : RecyclerView.ViewHolder {
private val adapter by lazy {
NestedAdapter().apply {
val layoutManager = LinearLayoutManager(containerView.context, LinearLayoutManager.HORIZONTAL, reverseLayout = false)
contacts_list.layoutManager = layoutManager
contacts_list.isNestedScrollingEnabled = false
contacts_list.adapter = this
}
}
fun bind(items: List<Item>) {
adapter.updateContacts(items)
}
}
class NestedAdapter : RecyclerView.Adapter {
private var items: List<Item> = emptyList()
fun updateItems(_items: List<Item>) {
val diff = DiffUtil.calculateDiff(...)
items = _items
diff.dispatchUpdatesTo(this)
}
...
}
我有这个问题,因为每个嵌套列表都创建了几个 ViewHolder。在调用 notifyItemChanged() 的地方(第 diff.dispatchUpdatesTo(this) 行),recyclerView 获取缓存的 viewHolder,为他调用 bind 并替换已经附加的 viewHolder。
https://android.jlelse.eu/anatomy-of-recyclerview-part-1-a-search-for-a-viewholder-continued-d81c631a2b91#.dcsykhoh9
为了解决这个问题,我允许 recyclerView 重用 NestedListViewHolder。
contacts_list.itemAnimator = object : DefaultItemAnimator() {
override fun canReuseUpdatedViewHolder(viewHolder: RecyclerView.ViewHolder, payloads: MutableList<Any>): Boolean {
return viewHolder is NestedListViewHolder || super.canReuseUpdatedViewHolder(viewHolder, payloads)
}
}
我有垂直的 recyclerView 和几个嵌套的水平 recyclerView。每个嵌套列表通过 DiffUtils 机制动态更新。
当我更新嵌套列表时,我等待滚动保持在相同位置并且新项目出现在它的右侧,但滚动之前在页面上进行。怎么回事?
class Adapter : RecyclerView.Adapter {
private var nestedItems: List<Item> = emptyList()
fun updateNestedList(items: List<Item>) {
val diff = DiffUtil.calculateDiff(...)
nestedItems = items
diff.dispatchUpdatesTo(this)
}
override fun onCreateViewHolder() {
when (itemType) {
...
ITEM_TYPE_HORIZONTAL -> NestedListViewHolder()
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
...
is NestedListViewHolder -> (holder as NestedListViewHolder).bind(items)
}
}
}
class NestedListViewHolder : RecyclerView.ViewHolder {
private val adapter by lazy {
NestedAdapter().apply {
val layoutManager = LinearLayoutManager(containerView.context, LinearLayoutManager.HORIZONTAL, reverseLayout = false)
contacts_list.layoutManager = layoutManager
contacts_list.isNestedScrollingEnabled = false
contacts_list.adapter = this
}
}
fun bind(items: List<Item>) {
adapter.updateContacts(items)
}
}
class NestedAdapter : RecyclerView.Adapter {
private var items: List<Item> = emptyList()
fun updateItems(_items: List<Item>) {
val diff = DiffUtil.calculateDiff(...)
items = _items
diff.dispatchUpdatesTo(this)
}
...
}
我有这个问题,因为每个嵌套列表都创建了几个 ViewHolder。在调用 notifyItemChanged() 的地方(第 diff.dispatchUpdatesTo(this) 行),recyclerView 获取缓存的 viewHolder,为他调用 bind 并替换已经附加的 viewHolder。 https://android.jlelse.eu/anatomy-of-recyclerview-part-1-a-search-for-a-viewholder-continued-d81c631a2b91#.dcsykhoh9
为了解决这个问题,我允许 recyclerView 重用 NestedListViewHolder。
contacts_list.itemAnimator = object : DefaultItemAnimator() {
override fun canReuseUpdatedViewHolder(viewHolder: RecyclerView.ViewHolder, payloads: MutableList<Any>): Boolean {
return viewHolder is NestedListViewHolder || super.canReuseUpdatedViewHolder(viewHolder, payloads)
}
}