在顶部添加新项后,Recycler视图未滚动到顶部,因为尚未对列表适配器进行更改

时间:2018-08-17 05:54:07

标签: android android-recyclerview kotlin android-architecture-components

我正在从实时数据中获取带有新项的新列表,然后使用其数据来更新适配器

viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) 
        recyclerView.scrollToPosition(0)
}

5 个答案:

答案 0 :(得分:4)

submitList在后​​台线程上工作,因此总会存在无法解决延迟的竞争条件。幸运的是,我们可以使用RecyclerView.AdapterDataObserver回调函数在列表计算完成时得到通知:

yourRecyclerViewAdapter.registerAdapterDataObserver(object: RecyclerView.AdapterDataObserver() {
    override fun onChanged() {
        recycler_view_list.scrollToPosition(0)
    }
    override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
        recycler_view_list.scrollToPosition(0)
    }
    override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
        recycler_view_list.scrollToPosition(0)
    }
    override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
        recycler_view_list.scrollToPosition(0)
    }
    override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
        recycler_view_list.scrollToPosition(0)
    }
    override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
        recycler_view_list.scrollToPosition(0)
    }
})

viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) 
}

答案 1 :(得分:1)

感谢大家的回应。但是对我有用的唯一工作是在执行submitList之后延迟1秒。即使不适当,但由于以下原因起作用:

adapter.submitList()将始终花费相同的执行时间(以毫秒为单位)

我刚刚打电话

Handler().postDelayed ({
  recycler.scrollToPosition(0)
}, 1000)

答案 2 :(得分:0)

您也可以使用

recyclerView.smoothScrollToPosition(0);

viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) 
         recyclerView.smoothScrollToPosition(0);
}

答案 3 :(得分:0)

使用这种方式

viewModel.myLiveData.observe { this, Observer { myList -> 
    adapter.submitList(myList) // Assuming you are notifying adapter by notifydatasetchanged()
    recyclerView.post { recyclerView.scrollToPosition(0) }
}

这里post给UI线程一些时间来用新数据填充Recycler,然后调用scrollToPosition

答案 4 :(得分:-1)

解决此问题的另一种方法是将Recyclerview包装在嵌套ScrollView中。

 <android.support.v4.widget.NestedScrollView
    android:id="@+id/nsv_data"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
           <android.support.v7.widget.RecyclerView
                android:id="@+id/rv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:nestedScrollingEnabled="false"
                tools:listitem="@layout/rv_interview_prep_row"
                android:visibility="gone"
                android:background="@color/white" />
</android.support.v4.widget.NestedScrollView>

然后在“活动”或“片段”中。

viewModel.myLiveData.observe { this, Observer { myList -> 
    adapter.submitList(myList) 
    nestedScrollView.scrollTo(0,0);
}