Keeping states of recyclerview in fragment with paging library and navigation architecture component Keeping states of recyclerview in fragment with paging library and navigation architecture component android android

Keeping states of recyclerview in fragment with paging library and navigation architecture component


On fragment's onSaveinstanceState save the layout info of the recyclerview:

    @Override    public void onSaveInstanceState(@NonNull Bundle outState) {        super.onSaveInstanceState(outState);        outState.putParcelable(KEY_LAYOUT, myRecyclerView.getLayoutManager().onSaveInstanceState());    }

and on onActivityCreated, restore the scroll position:

    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        if (savedInstanceState != null) {           myRecyclerView.getLayoutManager().onRestoreInstanceState(                    savedInstanceState.getParcelable(KEY_LAYOUT));        }    }


Since you use NavController, you cannot keep the view of the list fragment when navigating.

What you could do instead is to keep the data of the RecyclerView, and use that data when the view is recreated after back navigation.

The problem is that your adapter and the singersPagination is created anew every time the view of the fragment is created. Instead,

  1. Move singersAdapter to a field:

    private val singersAdapter = HomeSingersAdapter()
  2. Move this part to onAttach

    getSingersPagination().observe(viewLifecycleOwner, Observer {    singersAdapter.submitList(it)})
  3. Call retainInstance(true) in onAttach. This way even configuration changes won't reset the state.


The sample fragment code you posted does not correspond to the problem description, I guess it's just an illustration of what you do in your app.

In the sample code, the actual navigation (the fragment transaction) is hidden behind this line:

findNavController().navigate(SplashFragmentDirections.actionSplashFragmentToSingerFragment2())

The key is how the details fragment is attached.

Based on your description, your details fragment is probably attached with FragmentTransaction.replace(int containerViewId, Fragment fragment). What this actually does is first remove the current list fragment and then add the detail fragment to the container. In this case, the state of the list fragment is not kept. When you press the back button, the onViewCreated of the list fragment will run again.

To keep the state of your list fragment, you should use FragmentTransaction.add(int containerViewId, Fragment fragment) instead of replace. This way, the list fragment remains where it is and it gets "covered" by the detail fragment. When you press the back button, the onViewCreated will not be called, since the view of the fragment did not get destroyed.