1

我有垂直 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)
    }
    ...
}
4

1 回答 1

3

我有这个问题,因为每个嵌套列表都创建了几个 ViewHolders。在调用 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)
        }
    }
于 2019-07-19T07:24:23.887 回答