2

我有一个ParentData结构如下的类:

class ParentData(
//parent data fields 
var childList: List<ChildData>

我正在使用列表填充父 RecylerView,ParentData然后使用嵌入的父 RecylerView 适配器(ListAdapter)填充每个嵌套的子 RecyclerView,List<ChildData>如下onBindViewHolder所示:

val mAdapter = ChildAdapter()

binding.childRecyclerView.apply {
    layoutManager = LinearLayoutManager(this.context)
    adapter = mAdapter
}

mAdapter.submitList(item.childList)
//item from getItem(position)

我观察到 a LiveData<List<ParentData>>,所以每次嵌入ChildData更改时,我都会将新的提交List<ParentData>给我的父回收器,后者又会调用OnBindViewHolder并提交新的 `childList' 并更新内部子 RecyclerView。

val mAdapter = ChildAdapter()每次更新数据时都会调用该问题,重置整个子 RecyclerView。这导致看不到任何项目添加动画并且滚动位置被重置。

有什么方法可以避免每次都初始化一个新的适配器,或者我可以通过其他方式避免重置子 RecyclerViews?

4

1 回答 1

0

我知道这是一个老问题,但我从事过一个完全一样的项目,这个答案可能对其他人有所帮助。

基本上我们有一个单一的 RecyclerView 方法,其中主界面有一个 Parent RecyclerView,它接收 Pair<ViewType, BaseViewBinder> 的列表。

class ParentAdapter: RecyclerView.Adapter<BaseViewHolder>() {

    private var mList: List<Pair<Int, BaseViewBinder>> = listOf() //Int is the ViewType

    fun updateData(mList: List<Pair<Int, BaseViewBinder>>) {
        if (this.mList!= mList) {
            this.mList = mList
            this.notifySetDataChanged()
...

我们观察到每次有新数据时都会向父 RecyclerView 提供一个新列表的 MediatorLiveData。

问题是 this.notifySetDataChanged() 将更新父 recyclerview 中的所有内容。因此,通过向 ParentAdapter“updateData”函数发送一个额外的变量,通知列表中的哪个视图类型已更改,解决了子 RecyclerViews“重置”并在收到新列表时滚动回开始的问题,因此我们可以“notifyItemChanged”仅是列表的特定索引,因此不会刷新整个 recyclerview ui。

fun updateData(mList: List<Pair<Int, BaseViewBinder>>, sectionUpdated: Int) {
        if (this.mList!= mList) {
            this.mList = mList
            
            when(sectionUpdated){
               SECTION_A -> this.notifyItemChanged(mList.indexOfFirst { it.first == VIEW_TYPE_A })
               SECTION_B -> this.notifyItemChanged(mList.indexOfFirst { it.first == VIEW_TYPE_B })
               SECTION_C -> this.notifyItemChanged(mList.indexOfFirst { it.first == VIEW_TYPE_C })
            }

所以基本上你需要编辑生成你的 LiveData 的任何函数,检查新数据中的差异,并返回列表和一个 Int 指定那个特定的孩子发生了变化。前任:

    private var mListA: List<X>
    
    fun returnSomeLiveData(): LiveData<Pair<Int, List<X>>> {
        var result = MutableLiveData<Pair<Int, List<X>>>()

        if (mListA != someLiveData.value) { //could be DiffUtils
            mListA = someLiveData.value

            result.postValue(Pair(0, mListA))
        }
        return result
    }

    companion object {
        val SECTION_A = 0
        val SECTION_B = 1
        val SECTION_C = 2
    }    
于 2021-02-04T04:45:45.713 回答