I am getting the new list with new item at the start in my live data and then using its data to update the adapter
viewModel.myLiveData.observe { this, Observer { myList ->
adapter.submitList(myList)
recyclerView.scrollToPosition(0)
}
submitList
does its work on a background thread, so there will always be race conditions that delays can't solve. Fortunately, we can use a RecyclerView.AdapterDataObserver
callback to be informed when the list calculations are complete:
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)
}
Use this way
viewModel.myLiveData.observe { this, Observer { myList ->
adapter.submitList(myList) // Assuming you are notifying adapter by notifydatasetchanged()
recyclerView.post { recyclerView.scrollToPosition(0) }
}
Here post
is giving UI Thread some time to populate Recycler with new data and then call scrollToPosition
.
Thank you everyone for response. But the only work that did worked for me was to place a 1 second delay after executing submitList. Even though not appropriate one, But works for the following reason:
adapter.submitList()
will always take the same execution time (within milliseconds)
I just called
Handler().postDelayed ({
recycler.scrollToPosition(0)
}, 1000)
You can also use
recyclerView.smoothScrollToPosition(0);
viewModel.myLiveData.observe { this, Observer { myList ->
adapter.submitList(myList)
recyclerView.smoothScrollToPosition(0);
}
Another way to Solve this Problem is wrapping the Recyclerview inside the Nested 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>
Then inside your Activity or Fragment.
viewModel.myLiveData.observe { this, Observer { myList ->
adapter.submitList(myList)
nestedScrollView.scrollTo(0,0);
}