gpt4 book ai didi

android - AsyncListDiffer onAfterSubmitList 监听器

转载 作者:行者123 更新时间:2023-11-29 02:21:31 25 4
gpt4 key购买 nike

我试图调用 recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,null,0) 只有在 mDiffer.submitlist(list) 完成“比较”之后并为列表更新/更改设置动画。

我可以使用 onAfterSubmitList(Callback callback) 的 AsyncListDiffer 特性来实现这一点吗?

如果没有,是否可以查明 submitList() 何时完成其任务,以便我可以将我的 scrollToPosition(0) 放在那里?

最佳答案

2020 年 7 月更新:

Google 为此添加了回调!请参阅:https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#submitList(java.util.List%3CT%3E,%20java.lang.Runnable)

以前的回答,来自糟糕的过去:

首先,我无法相信 Google 没有为此提供回调。

我深入研究了 AsyncListDiffer 的源代码,我发现当所有的 RecyclerView 更新都完成后,可以接收到一个回调——但是接收这个回调的方式很奇怪。

您需要创建一个 BatchingListUpdateCallback 的子类,然后将您的 ListUpdateCallback(或大多数情况下的 AdapterListUpdateCallback)包装在其中.

然后,您应该覆盖 dispatchLastEventAsyncListDiffer 将在所有但其中一个更新已被分派(dispatch)之后调用它。在您的 dispatchLastEvent 中,您需要调用 super 实现,这样您就不会破坏任何东西。您还需要调用自定义回调,这是您的方式。

在 Kotlin 中看起来像:

class OnDiffDoneListUpdateCallback(
listUpdateCallback: ListUpdateCallback,
private val onDiffDoneCallback: () -> Unit
) : BatchingListUpdateCallback(listUpdateCallback) {
override fun dispatchLastEvent() {
super.dispatchLastEvent()
onDiffDoneCallback()
}
}

最后一步是将您的自定义 OnDiffDoneListUpdateCallback 提供给 AsyncListDiffer。为此,您需要自己初始化 AsyncListDiffer - 如果您使用的是 ListAdapter 或类似的东西,则需要重构以便控制AsyncListDiffer

在 Kotlin 中,它看起来像:

private val asyncListDiffer = AsyncListDiffer<ItemType>(
OnDiffDoneListUpdateCallback(AdapterListUpdateCallback(adapter)) {
// here's your callback
doTheStuffAfterDiffIsDone()
},
AsyncDifferConfig.Builder<ItemType>(diffCallback).build()
)

编辑:当然,我忘记了边缘情况!

有时,dispatchLastEvent 不会被调用,因为 AsyncListDiffer 认为更新微不足道。这是它所做的检查:

    if (newList == mList) {
...
return;
}

// fast simple remove all
if (newList == null) {
...
mUpdateCallback.onRemoved(0, countRemoved);
return;
}

// fast simple first insert
if (mList == null) {
...
mUpdateCallback.onInserted(0, newList.size());
return;
}

我建议您自己进行这些检查,就在您调用 asyncListDiffer.submitList(list) 之前。但当然,这不可能那么容易! mList 是私有(private)的,如果 mList 为 null,getCurrentList 将返回一个空列表,因此对于此检查没有用。相反,您必须使用反射来访问它:

    val listField = AsyncListDiffer::class.java.getDeclaredField("mList")
listField.isAccessible = true
val asyncDifferList = listField.get(asyncListDiffer) as List<ItemType>?

asyncListDiffer.submitList(newList)

if(asyncDifferList == null) {
onDiffDone()
}
if(newList == null) {
onDiffDone()
}
if(newList == asyncDifferList) {
onDiffDone()
}

编辑 2:现在,我知道你在说什么 - 肯定有更简单、更简单的方法来做到这一点?答案是……是的!只需将整个 AsyncListDiffer 类复制到您的项目中,然后自己添加回调即可!

关于android - AsyncListDiffer onAfterSubmitList 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55331449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com