Kotlin 如何在不丢失动画/初始化新适配器的情况下更新嵌套子RecyclerView中的数据?
我有一个Kotlin 如何在不丢失动画/初始化新适配器的情况下更新嵌套子RecyclerView中的数据?,kotlin,android-recyclerview,android-room,listadapter,nestedrecyclerview,Kotlin,Android Recyclerview,Android Room,Listadapter,Nestedrecyclerview,我有一个ParentData类,其结构如下: class ParentData( //parent data fields var childList: List<ChildData> 我观察到一个LiveData,因此每次嵌入的ChildData更改时,我都会将新的列表提交给我的父回收器,父回收器依次调用OnBindViewHolder并提交新的“childList”并更新内部的子回收器视图 问题是每次更新数据时都会调用val mAdapter=ChildAdapter(),从
ParentData
类,其结构如下:
class ParentData(
//parent data fields
var childList: List<ChildData>
我观察到一个LiveData
,因此每次嵌入的ChildData
更改时,我都会将新的列表提交给我的父回收器,父回收器依次调用OnBindViewHolder
并提交新的“childList”并更新内部的子回收器视图
问题是每次更新数据时都会调用val mAdapter=ChildAdapter()
,从而重置整个子RecyclerView。这将导致看不到项目添加动画,并重置滚动位置
是否有任何方法可以避免每次初始化一个新适配器,或者有其他方法可以避免重置子RecyclerViews 我知道这是一个老问题,但我参与过一个与之完全相同的项目,这个答案可能会帮助其他人
基本上,我们有一个单一的RecyclerView方法,其中主接口有一个父RecyclerView,它接收一个对的列表
类ParentAdapter:RecyclerView.Adapter(){
private var mList:List=listOf()//Int是视图类型
乐趣更新数据(列表:列表){
if(this.mList!=mList){
this.mList=mList
this.notifySetDataChanged()
...
我们观察到一个MediatorLiveData,每当有新数据时,它就会向父RecyclerView提供一个新列表
问题是.notifySetDataChanged()将更新父recyclerview中的所有内容。因此,通过向ParentAdapter“updateData”发送一个额外变量,解决了接收到新列表时,子RecyclerViews“重置”并滚动回Begging的问题函数通知列表中的哪个视图类型已更改,因此我们只能“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 })
}
fun updateData(mList:List,sectionUpdated:Int){
if(this.mList!=mList){
this.mList=mList
何时(更新部分){
节A->this.notifyItemChanged(mList.indexOfFirst{it.first==视图类型A})
节\u B->this.notifyItemChanged(mList.indexOfFirst{it.first==视图\u类型\u B})
节C->this.notifyItemChanged(mList.indexOfFirst{it.first==视图类型C})
}
因此,基本上,您需要编辑生成LiveData的任何函数,检查新数据中的差异,并返回列表和指定特定子项已更改的Int。
例:
private-var-mListA:List
fun returnSomeLiveData():LiveData{
var result=MutableLiveData()
如果(mListA!=someLiveData.value){//可以是DiffUtils
mListA=someLiveData.value
结果.后置值(对(0,mListA))
}
返回结果
}
伴星{
val截面_A=0
val截面_B=1
val截面_C=2
}
将mAdapter.submitList(item.childList)放入oberver。
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()
...
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 })
}
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
}