Fragment
class HomeFragment : Fragment() { private val viewModel: HomeViewModel by viewModels() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) initList() } override fun onDestroyView() { super.onDestroyView() viewModel.listState = list.layoutManager?.onSaveInstanceState() } private fun initList() { val query = ... val options: FirestoreRecyclerOptions<Post> = FirestoreRecyclerOptions.Builder<Post>() .setQuery(query, SnapshotParser { doc -> // replace with your own implementation Post.toObject(doc) }) .setLifecycleOwner(this) .build() adapter = LocalAdapter(options, viewModel) // this doesn't work as onItemRangeInserted is called multiple times (one by one) /* adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { if (viewModel.listState != null) { list.layoutManager?.onRestoreInstanceState(viewModel.listState) viewModel.listState = null } } }) */ // use this instead adapter.snapshots.addChangeEventListener(object : ChangeEventListener { override fun onDataChanged() { Timber.d(" Data Changed") if (viewModel.listState != null) { list.layoutManager?.onRestoreInstanceState(viewModel.listState) viewModel.listState = null } } override fun onChildChanged( type: ChangeEventType, snapshot: DocumentSnapshot, newIndex: Int, oldIndex: Int ) { } override fun onError(e: FirebaseFirestoreException) { } }) list.adapter = adapter }}
NOTE: I am using Jetpack Navigation, so I listen to onDestroyView
to save state (when navigate to another fragment).
ViewModel
class HomeViewModel : ViewModel() { var listState: Parcelable? = null}