Search code examples
androidandroid-recyclerviewonsaveinstancestate

how to store recyclerview data on onSaveInstanceState


I want to save data from the API in the RecyclerView so that when rotating the screen is not reloaded

I think I can use onSaveInstanceState but still don't really understand how to use it

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    final RecyclerView rvTVShow = view.findViewById(R.id.rv_shows);
    rvTVShow.setHasFixedSize(true);
    rvTVShow.setLayoutManager(new LinearLayoutManager(getActivity()));

    ApiInterface apiService =
            ApiClient.getClient().create(ApiInterface.class);
    Call<MovieResponse> call = apiService.getTVShow(API_KEY);
    call.enqueue(new Callback<MovieResponse>() {

        @Override
        public void onResponse(@NonNull Call<MovieResponse> call, @NonNull Response<MovieResponse> response) {
            final List<Movies> movies = Objects.requireNonNull(response.body()).getResults();

           TvShowAdapter tvShowAdapter = new TvShowAdapter(movies , R.layout.list_movies);
           rvTVShow.setAdapter(tvShowAdapter);

           ....
        }

Solution

  • I will explain how savedInstanceState works while refactoring your code.

    First: Create a global Movie object and an Adapter for it

      List<Movies> movies = new ArrayList();
      TvShowAdapter tvShowAdapter = null;
    

    Re-initialize adapter under activity onCreate

      tvShowAdapter = new TvShowAdapter(movies , R.layout.list_movies);
           rvTVShow.setAdapter(tvShowAdapter);
    

    Create a new method to handle movie data population

     public void populateRV(List<Movies> movies)
    {
          this.movies = movies;
       //notify adapter about the new record
          tvShowAdapter.notifyDataSetChanged(); 
     }
    

    Insert data to Movies object under your Response callback

      movies = Objects.requireNonNull(response.body()).getResults();
     populateRV(movies);
    

    Everytime the orientation of an activity changes Android resets the states of all views by redrawing them. This causes non persistent data to be lost. But before redrawing views it calls the method onSavedInstanceState

    Hence we can prevent state loss by saving the state of our views using the already defined onSavedInstanceState method provided by android.

    Add the following block inside the overridden onSavedInstanceState method of your activity

     //this saves the data to a temporary storage
     savedInstanceState.putParcelableArrayList("movie_data", movies);
     //call super to commit your changes
     super.onSaveInstanceState(savedInstanceState);
    

    Next is to recover the data after orientation change is completed

    Add the following block in your activity onCreate and make sure it comes after initializing your adapter

     //...add the recyclerview adapter initialization block here before checking for saved data
    
     //Check for saved data
     if (savedInstanceState != null) {
     // Retrieve the data you saved
     movies = savedInstanceState.getParcelableArrayList("movie_data");
    
      //Call method to reload adapter record
     populateRV(movies);
     } else {
     //No data to retrieve
    //Load your API values here.
     }