ListAdapter SubmitList()-如何滚动到开头

时间:2018-11-11 12:24:58

标签: android android-recyclerview listadapter

我的RecyclerView和ListAdapter出现问题。

通过API,我收到的物品从旧到新的升序。

然后通过调用submitList(items)方法刷新我的列表。

但是,由于一切都是异步的,因此在接收到第一个项目后,RecyclerView会保留在接收并显示的第一个项目的位置。 由于在ListAdapter类中,当commitList()方法完成时没有回调,因此在更新到已添加的新项目之一之后,我找不到滚动的方法。

是否有一种方法可以在ListAdapter更新时进行拦截?

4 个答案:

答案 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)

documentation如下:

  

在更新当前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) }