我将RecyclerView
与AsyncListDiffer
一起使用(计算和动画化旧项目和新项目之间的差异,所有这些都在后台线程上。)
我有一个按钮可以对列表进行排序。在对它进行排序并使用RecyclerView
将其重新设置为mDiffer.submitList(items);
之后,我也调用了recyclerView.scrollToPosition(0)
或(smoothScrollToPosition(0)
),但是它没有任何作用。
我认为这种行为是可以预期的,因为AsyncListDiffer
可能在调用scrollToPosition(0)
时仍在计算差异,因此它没有任何作用。此外,默认情况下,AsyncListDiffer
不会回滚到顶部,而是使RecyclerView保持相同的状态。
但是如何RecyclerView
完成并更新后告诉AsyncListDiffer
滚动到顶部?
答案 0 :(得分:1)
在这里得到了答案:
https://stackoverflow.com/a/55264063/1181261
基本上,如果您以不同的顺序提交相同的列表,它将被忽略。因此,您首先需要submit(null)
,然后提交重新排序的列表。
答案 1 :(得分:1)
我担心,尽管.submitList(null)
为您服务,但它只会刷新整个RecyclerView,而不会呈现所需的动画列表更新。
解决方案是在ListAdapter内部实现.submitList( List<T> list)
方法,如下所示:
public void submitList(@Nullable List<T> list) {
mDiffer.submitList(list != null ? new ArrayList<>(list) : null);
}
通过这种方式,您可以允许ListAdapter保留其currentList,并使其与newList“差异”,从而进行动画更新,而不是与null
“差异”。
答案 2 :(得分:1)
如果查看AsyncListDiffer
的{{1}}的javadocs,您会注意到第二个参数是submitList
,它是在将项目提交到适配器之后执行的: / p>
Runnable
所以你想要的是这个(这是Kotlin顺便说一句):
/**
* Pass a new List to the AdapterHelper. Adapter updates will be computed on a background
* thread.
* <p>
* If a List is already present, a diff will be computed asynchronously on a background thread.
* When the diff is computed, it will be applied (dispatched to the {@link ListUpdateCallback}),
* and the new List will be swapped in.
* <p>
* The commit callback can be used to know when the List is committed, but note that it
* may not be executed. If List B is submitted immediately after List A, and is
* committed directly, the callback associated with List A will not be run.
*
* @param newList The new List.
* @param commitCallback Optional runnable that is executed when the List is committed, if
* it is committed.
*/
或使用Java
adapter.submitList(items) {
// This will run after items have been set in the adapter
recyclerView.scrollToPosition(0)
}