我知道这是一个老问题,但我从事过一个完全一样的项目,这个答案可能对其他人有所帮助。
基本上我们有一个单一的 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
}