我的RecyclerView和ListAdapter出现问题。
通过API,我收到的物品从旧到新的升序。
然后通过调用submitList(items)方法刷新我的列表。
但是,由于一切都是异步的,因此在接收到第一个项目后,RecyclerView会保留在接收并显示的第一个项目的位置。 由于在ListAdapter类中,当commitList()方法完成时没有回调,因此在更新到已添加的新项目之一之后,我找不到滚动的方法。
是否有一种方法可以在ListAdapter更新时进行拦截?
答案 0 :(得分:14)
Kotlin:非常简单的方法来做到这一点。
listAdapter.submitList( yourNewList, Runnable {
yourRecyclerView.scrollToPosition(0)
})
答案 1 :(得分:5)
不是特定于ListAdapter的,但是它仍然可以工作:
只需使用adapter.registerAdapterDataObserver(RecyclerView.AdapterDataObserver)
并覆盖相关的onItemXXX方法即可告诉RecyclerView滚动到任何位置。
例如:
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
(recycler_view.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(positionStart, 0)
}
})
答案 2 :(得分:3)
要覆盖的方法称为:
public void onCurrentListChanged(List<T> previousList, List<T> currentList)
在更新当前
List
时调用。
ListAdapter
的内联文档显示为:
此类是
AsyncListDiffer
周围的便利包装,它实现了Adapter通用的默认行为,用于项目访问和计数。
,随后显示为:
希望对适配器行为进行更多控制或提供特定基类的高级用户应参考
AsyncListDiffer
,它提供了从diff事件到适配器位置的自定义映射。
这意味着,您需要扩展常规RecyclerView.Adapter
,并结合AsyncListDiffer
的自定义实现;而不是ListAdapter
(它只是一个便利包装,具有所述基本功能)。
您可以使用ListAdapter
类作为模板(不扩展它,这是线索),但是可以扩展并重用所得的类。否则就没有机会控制所需的回调。
答案 3 :(得分:1)
我检查了ListAdapter
源代码,发现有onCurrentListChanged方法。
您可以简单地在自定义适配器中覆盖它。您还可以将侦听器传递给适配器以捕获事件,并将RecyclerView滚动到开头。
您的适配器:
typealias ListChangeListener = () -> Unit
class Adapter(private val listChangeListener: ListChangeListener) : ListAdapter<Item, Adapter.ViewHolder>(Callback) {
override fun onCurrentListChanged(previousList: List<Item>, currentList: List<Item>) {
super.onCurrentListChanged(previousList, currentList)
// Call your listener here
listChangeListener()
}
// Other methods and ViewHolder class
}
在“活动”或“片段”中创建适配器:
recyclerView.adapter = Adapter { recyclerView.scrollToPosition(0) }