I'm reloading recyclerView data every 15s. To keep scroll position when switching between apps, I use onSaveInstanceState() and onRestoreInstanceState(mRVState) methods in corresponding fragment overriden methods. But when I wanted to save position while switching between different fragments, I came up with this solution:
1.Set RecyclerView.OnScrollListener() in onResume() method of Fragment and get current first visible item position on each scroll. As you can see position variable is located in parent activity, so it's not lost on fragment replacement:
override fun onResume() {
super.onResume()
if (updateListRunnable != null) setAndRunUpdateListRunnable()
mRV?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
mainActivity.lastRVPosition =
(recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
}
})
}
2.Use scrollToPosition() method of recyclerView after data has been replaced inside adapter:
private fun setDataList(dataList: List<Data?>?) {
val mutableDataList = dataList?.toMutableList()
val currentItemCount = binding?.rvDataList?.adapter?.itemCount
if (currentItemCount == null || currentItemCount == 0) {
// create new adapter with initial data
val adapter = DataListAdapter(mutableDataList, baseVM, mainVM)
binding?.rvDataList?.adapter = adapter
binding?.rvDataList?.layoutManager = LinearLayoutManager(context)
mRV?.scrollToPosition(mainActivity.lastRVPosition);
} else {
// update existing adapter with updated data
mRVState = mRV?.layoutManager?.onSaveInstanceState()
val currentAdapter = binding?.rvDataList?.adapter as? DataListAdapter
currentAdapter?.updateDataList(dataList)
currentAdapter?.notifyDataSetChanged()
mRV?.layoutManager?.onRestoreInstanceState(mRVState)
mRV?.scrollToPosition(mainActivity.lastRVPosition);
}
}
As you can see I also use onSaveInstanceState()/onRestoreInstanceState() before/after replacing data, so that if there was no scroll before data replacement, position will still be saved. Scroll listener saved position is only useful when switching between fragments.