How to properly restore view state on rotation?












0















I know this question relates to this question
RecyclerView store / restore state between activities but it is specific to my own problem, maybe you can help. I won't post all the code as there is a LOT of it.



In the MainActivity below I want follow what what is suggested in that answer, the only difference is that I use SharePreference to distinguish between what view was last on the screen. For some reason it still loads the items for layoutManager on rotation. Not only this, but it does not even save the state of that view, it just resets. I posted all the code from this Activity in the hopes that someone can spot where I went wrong. I can also post the github link if needed. Whole app can not be used unless you have API key described in the github. Please let me know if you need the AndroidManifest or anything else.



public class MainActivity extends AppCompatActivity implements PosterAdapter.PosterItemClickHandler, FavoritesAdapter.FavoritesClickHandler {

private PosterAdapter posterAdapter;
private FavoritesAdapter favoritesAdapter;
private GridLayoutManager layoutManager;
private GridLayoutManager layoutManager1;
private MovieDataBase mDb;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private final String FavoriteViewState = "favorites-view-state";
private boolean VIEWSTATE1;
private Parcelable favListState;
private final String FavListKey = "favorites-key";
private Bundle mBundleRecyclerViewState;



@BindView(R.id.rv_posters)RecyclerView mRecyclerViews;
@BindView(R.id.tv_error_message1) TextView mErrorMessage1;
@BindView(R.id.tv_error_message2) TextView mErrorMessage2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ButterKnife.bind(this);
mDb = MovieDataBase.getInstance(getApplicationContext());

setRecyclerViews();
updateUI(popularSortLink);
loadFavoritesData();

prefs = PreferenceManager.getDefaultSharedPreferences(this);

if(savedInstanceState != null){
boolean favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);
if(favoritesState) {
favListState = savedInstanceState.getParcelableArrayList(FavListKey);
//List<MovieEntry> movies = new ArrayList<>(favListState);
if(favListState != null) {
favoritesAdapter = new FavoritesAdapter(favListState, MainActivity.this);
//favoritesAdapter.setFavorites(favListState);
mRecyclerViews.setLayoutManager(layoutManager1);
mRecyclerViews.setHasFixedSize(false);
mRecyclerViews.setAdapter(favoritesAdapter);
}
}
}
}


// This method sets the recycler views for the main screen
public void setRecyclerViews(){
// Create the grid layout and apply it to the poster recycler view
layoutManager = new GridLayoutManager(this,3);
layoutManager1 = new GridLayoutManager(this,1);
mRecyclerViews.setLayoutManager(layoutManager);
mRecyclerViews.setHasFixedSize(true);

}

// This method updates the UI based on whether there is a network connection or not.
public void updateUI(String movieLink){
if(!isOnline()){
mErrorMessage1.setVisibility(View.VISIBLE);
mRecyclerViews.setVisibility(View.INVISIBLE);
}else{
mErrorMessage1.setVisibility(View.INVISIBLE);
mRecyclerViews.setVisibility(View.VISIBLE);
startApp(movieLink);
}
}

//Information sourced from https://developer.android.com/training/volley/requestqueue
//09/11/18
// This method makes a network request using Androids Volley mechanisms to retrieve the json data
private void startApp(String movieLink){
RequestQueue mRequestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);
// Start the queue
mRequestQueue.start();

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, movieLink, null, new Response.Listener<JSONObject>() {

@Override
public void onResponse(JSONObject response) {

setRecyclerViews();
mErrorMessage2.setVisibility(View.INVISIBLE);
mRecyclerViews.setVisibility(View.VISIBLE);
VIEWSTATE1 = false;
editor = prefs.edit();
editor.putBoolean(FavoriteViewState, VIEWSTATE1);
editor.apply();

//Parse the JSON string and store in a list of Movie objects
List<MovieDetails> movieDetailsList = JsonUtility.parseMovieDetailsJson(response);

// display the data
loadMovieData(movieDetailsList);
}
}, new Response.ErrorListener() {

@Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
Log.i("TAG", error.toString());
mErrorMessage2.setVisibility(View.VISIBLE);
mRecyclerViews.setVisibility(View.INVISIBLE);
VIEWSTATE1 = false;
editor = prefs.edit();
editor.putBoolean(FavoriteViewState, VIEWSTATE1);
editor.apply();
}
});
mRequestQueue.add(jsonObjectRequest);
}

public void loadMovieData(List movieDetailsList){
//Create the adapter using the MovieDetails lists and apply the adapter to the recycler view
posterAdapter = new PosterAdapter(movieDetailsList, this);
mRecyclerViews.setAdapter(posterAdapter);
}

// This method views changes in the favorites database and updates it's cooresponding recycler view
public void loadFavoritesData(){
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getMovies().observe(this, new Observer<List<MovieEntry>>() {
@Override
public void onChanged(@Nullable List<MovieEntry> movieEntries) {
Log.d("TAG", "UPDATE FROM THE DATABASE using livedata in viewmodel");
favoritesAdapter = new FavoritesAdapter(movieEntries, MainActivity.this);
}
});

}


//This method updates the main view to show the favorites list
public void showFavsList(){


mRecyclerViews.setLayoutManager(layoutManager1);
mRecyclerViews.setHasFixedSize(false);
mRecyclerViews.setAdapter(favoritesAdapter);
mErrorMessage1.setVisibility(View.INVISIBLE);
VIEWSTATE1 = true;
editor = prefs.edit();
editor.putBoolean(FavoriteViewState, VIEWSTATE1);
editor.apply();
}

@Override //This method opens the next activity and loads data based on the index passed through from the adapter onClick method
public void onPosterItemClick(MovieDetails movieDetails) {

String parcelData = MainActivity.this.getString(R.string.parcel_data);
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra(parcelData, movieDetails);
startActivity(intent);
}

@Override //Override this method to inflate the menu resource
public boolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.sort_by, menu);
return true;
}

@Override //Handle clicks on certain menu items. In this case it handles the sorting methods.
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

if(id == R.id.popular_sort){
updateUI(popularSortLink);
return true;
}else if(id == R.id.rating_sort){
updateUI(topRatingSortLink);
return true;
}else if(id == R.id.favorites_sort){
// display the favorites list
showFavsList();
return true;
}
return super.onOptionsItemSelected(item);
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);

//Log.d("TEST", String.valueOf(favoritesState));
if(favoritesState){
outState.putParcelableArrayList(FavListKey,favListState);
}
}
}









share|improve this question





























    0















    I know this question relates to this question
    RecyclerView store / restore state between activities but it is specific to my own problem, maybe you can help. I won't post all the code as there is a LOT of it.



    In the MainActivity below I want follow what what is suggested in that answer, the only difference is that I use SharePreference to distinguish between what view was last on the screen. For some reason it still loads the items for layoutManager on rotation. Not only this, but it does not even save the state of that view, it just resets. I posted all the code from this Activity in the hopes that someone can spot where I went wrong. I can also post the github link if needed. Whole app can not be used unless you have API key described in the github. Please let me know if you need the AndroidManifest or anything else.



    public class MainActivity extends AppCompatActivity implements PosterAdapter.PosterItemClickHandler, FavoritesAdapter.FavoritesClickHandler {

    private PosterAdapter posterAdapter;
    private FavoritesAdapter favoritesAdapter;
    private GridLayoutManager layoutManager;
    private GridLayoutManager layoutManager1;
    private MovieDataBase mDb;
    private SharedPreferences prefs;
    private SharedPreferences.Editor editor;
    private final String FavoriteViewState = "favorites-view-state";
    private boolean VIEWSTATE1;
    private Parcelable favListState;
    private final String FavListKey = "favorites-key";
    private Bundle mBundleRecyclerViewState;



    @BindView(R.id.rv_posters)RecyclerView mRecyclerViews;
    @BindView(R.id.tv_error_message1) TextView mErrorMessage1;
    @BindView(R.id.tv_error_message2) TextView mErrorMessage2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ButterKnife.bind(this);
    mDb = MovieDataBase.getInstance(getApplicationContext());

    setRecyclerViews();
    updateUI(popularSortLink);
    loadFavoritesData();

    prefs = PreferenceManager.getDefaultSharedPreferences(this);

    if(savedInstanceState != null){
    boolean favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);
    if(favoritesState) {
    favListState = savedInstanceState.getParcelableArrayList(FavListKey);
    //List<MovieEntry> movies = new ArrayList<>(favListState);
    if(favListState != null) {
    favoritesAdapter = new FavoritesAdapter(favListState, MainActivity.this);
    //favoritesAdapter.setFavorites(favListState);
    mRecyclerViews.setLayoutManager(layoutManager1);
    mRecyclerViews.setHasFixedSize(false);
    mRecyclerViews.setAdapter(favoritesAdapter);
    }
    }
    }
    }


    // This method sets the recycler views for the main screen
    public void setRecyclerViews(){
    // Create the grid layout and apply it to the poster recycler view
    layoutManager = new GridLayoutManager(this,3);
    layoutManager1 = new GridLayoutManager(this,1);
    mRecyclerViews.setLayoutManager(layoutManager);
    mRecyclerViews.setHasFixedSize(true);

    }

    // This method updates the UI based on whether there is a network connection or not.
    public void updateUI(String movieLink){
    if(!isOnline()){
    mErrorMessage1.setVisibility(View.VISIBLE);
    mRecyclerViews.setVisibility(View.INVISIBLE);
    }else{
    mErrorMessage1.setVisibility(View.INVISIBLE);
    mRecyclerViews.setVisibility(View.VISIBLE);
    startApp(movieLink);
    }
    }

    //Information sourced from https://developer.android.com/training/volley/requestqueue
    //09/11/18
    // This method makes a network request using Androids Volley mechanisms to retrieve the json data
    private void startApp(String movieLink){
    RequestQueue mRequestQueue;
    // Instantiate the cache
    Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
    // Set up the network to use HttpURLConnection as the HTTP client.
    Network network = new BasicNetwork(new HurlStack());
    // Instantiate the RequestQueue with the cache and network.
    mRequestQueue = new RequestQueue(cache, network);
    // Start the queue
    mRequestQueue.start();

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
    (Request.Method.GET, movieLink, null, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {

    setRecyclerViews();
    mErrorMessage2.setVisibility(View.INVISIBLE);
    mRecyclerViews.setVisibility(View.VISIBLE);
    VIEWSTATE1 = false;
    editor = prefs.edit();
    editor.putBoolean(FavoriteViewState, VIEWSTATE1);
    editor.apply();

    //Parse the JSON string and store in a list of Movie objects
    List<MovieDetails> movieDetailsList = JsonUtility.parseMovieDetailsJson(response);

    // display the data
    loadMovieData(movieDetailsList);
    }
    }, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
    // TODO: Handle error
    Log.i("TAG", error.toString());
    mErrorMessage2.setVisibility(View.VISIBLE);
    mRecyclerViews.setVisibility(View.INVISIBLE);
    VIEWSTATE1 = false;
    editor = prefs.edit();
    editor.putBoolean(FavoriteViewState, VIEWSTATE1);
    editor.apply();
    }
    });
    mRequestQueue.add(jsonObjectRequest);
    }

    public void loadMovieData(List movieDetailsList){
    //Create the adapter using the MovieDetails lists and apply the adapter to the recycler view
    posterAdapter = new PosterAdapter(movieDetailsList, this);
    mRecyclerViews.setAdapter(posterAdapter);
    }

    // This method views changes in the favorites database and updates it's cooresponding recycler view
    public void loadFavoritesData(){
    MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
    viewModel.getMovies().observe(this, new Observer<List<MovieEntry>>() {
    @Override
    public void onChanged(@Nullable List<MovieEntry> movieEntries) {
    Log.d("TAG", "UPDATE FROM THE DATABASE using livedata in viewmodel");
    favoritesAdapter = new FavoritesAdapter(movieEntries, MainActivity.this);
    }
    });

    }


    //This method updates the main view to show the favorites list
    public void showFavsList(){


    mRecyclerViews.setLayoutManager(layoutManager1);
    mRecyclerViews.setHasFixedSize(false);
    mRecyclerViews.setAdapter(favoritesAdapter);
    mErrorMessage1.setVisibility(View.INVISIBLE);
    VIEWSTATE1 = true;
    editor = prefs.edit();
    editor.putBoolean(FavoriteViewState, VIEWSTATE1);
    editor.apply();
    }

    @Override //This method opens the next activity and loads data based on the index passed through from the adapter onClick method
    public void onPosterItemClick(MovieDetails movieDetails) {

    String parcelData = MainActivity.this.getString(R.string.parcel_data);
    Intent intent = new Intent(this, DetailActivity.class);
    intent.putExtra(parcelData, movieDetails);
    startActivity(intent);
    }

    @Override //Override this method to inflate the menu resource
    public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.sort_by, menu);
    return true;
    }

    @Override //Handle clicks on certain menu items. In this case it handles the sorting methods.
    public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if(id == R.id.popular_sort){
    updateUI(popularSortLink);
    return true;
    }else if(id == R.id.rating_sort){
    updateUI(topRatingSortLink);
    return true;
    }else if(id == R.id.favorites_sort){
    // display the favorites list
    showFavsList();
    return true;
    }
    return super.onOptionsItemSelected(item);
    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);

    //Log.d("TEST", String.valueOf(favoritesState));
    if(favoritesState){
    outState.putParcelableArrayList(FavListKey,favListState);
    }
    }
    }









    share|improve this question



























      0












      0








      0








      I know this question relates to this question
      RecyclerView store / restore state between activities but it is specific to my own problem, maybe you can help. I won't post all the code as there is a LOT of it.



      In the MainActivity below I want follow what what is suggested in that answer, the only difference is that I use SharePreference to distinguish between what view was last on the screen. For some reason it still loads the items for layoutManager on rotation. Not only this, but it does not even save the state of that view, it just resets. I posted all the code from this Activity in the hopes that someone can spot where I went wrong. I can also post the github link if needed. Whole app can not be used unless you have API key described in the github. Please let me know if you need the AndroidManifest or anything else.



      public class MainActivity extends AppCompatActivity implements PosterAdapter.PosterItemClickHandler, FavoritesAdapter.FavoritesClickHandler {

      private PosterAdapter posterAdapter;
      private FavoritesAdapter favoritesAdapter;
      private GridLayoutManager layoutManager;
      private GridLayoutManager layoutManager1;
      private MovieDataBase mDb;
      private SharedPreferences prefs;
      private SharedPreferences.Editor editor;
      private final String FavoriteViewState = "favorites-view-state";
      private boolean VIEWSTATE1;
      private Parcelable favListState;
      private final String FavListKey = "favorites-key";
      private Bundle mBundleRecyclerViewState;



      @BindView(R.id.rv_posters)RecyclerView mRecyclerViews;
      @BindView(R.id.tv_error_message1) TextView mErrorMessage1;
      @BindView(R.id.tv_error_message2) TextView mErrorMessage2;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      ButterKnife.bind(this);
      mDb = MovieDataBase.getInstance(getApplicationContext());

      setRecyclerViews();
      updateUI(popularSortLink);
      loadFavoritesData();

      prefs = PreferenceManager.getDefaultSharedPreferences(this);

      if(savedInstanceState != null){
      boolean favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);
      if(favoritesState) {
      favListState = savedInstanceState.getParcelableArrayList(FavListKey);
      //List<MovieEntry> movies = new ArrayList<>(favListState);
      if(favListState != null) {
      favoritesAdapter = new FavoritesAdapter(favListState, MainActivity.this);
      //favoritesAdapter.setFavorites(favListState);
      mRecyclerViews.setLayoutManager(layoutManager1);
      mRecyclerViews.setHasFixedSize(false);
      mRecyclerViews.setAdapter(favoritesAdapter);
      }
      }
      }
      }


      // This method sets the recycler views for the main screen
      public void setRecyclerViews(){
      // Create the grid layout and apply it to the poster recycler view
      layoutManager = new GridLayoutManager(this,3);
      layoutManager1 = new GridLayoutManager(this,1);
      mRecyclerViews.setLayoutManager(layoutManager);
      mRecyclerViews.setHasFixedSize(true);

      }

      // This method updates the UI based on whether there is a network connection or not.
      public void updateUI(String movieLink){
      if(!isOnline()){
      mErrorMessage1.setVisibility(View.VISIBLE);
      mRecyclerViews.setVisibility(View.INVISIBLE);
      }else{
      mErrorMessage1.setVisibility(View.INVISIBLE);
      mRecyclerViews.setVisibility(View.VISIBLE);
      startApp(movieLink);
      }
      }

      //Information sourced from https://developer.android.com/training/volley/requestqueue
      //09/11/18
      // This method makes a network request using Androids Volley mechanisms to retrieve the json data
      private void startApp(String movieLink){
      RequestQueue mRequestQueue;
      // Instantiate the cache
      Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
      // Set up the network to use HttpURLConnection as the HTTP client.
      Network network = new BasicNetwork(new HurlStack());
      // Instantiate the RequestQueue with the cache and network.
      mRequestQueue = new RequestQueue(cache, network);
      // Start the queue
      mRequestQueue.start();

      JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
      (Request.Method.GET, movieLink, null, new Response.Listener<JSONObject>() {

      @Override
      public void onResponse(JSONObject response) {

      setRecyclerViews();
      mErrorMessage2.setVisibility(View.INVISIBLE);
      mRecyclerViews.setVisibility(View.VISIBLE);
      VIEWSTATE1 = false;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();

      //Parse the JSON string and store in a list of Movie objects
      List<MovieDetails> movieDetailsList = JsonUtility.parseMovieDetailsJson(response);

      // display the data
      loadMovieData(movieDetailsList);
      }
      }, new Response.ErrorListener() {

      @Override
      public void onErrorResponse(VolleyError error) {
      // TODO: Handle error
      Log.i("TAG", error.toString());
      mErrorMessage2.setVisibility(View.VISIBLE);
      mRecyclerViews.setVisibility(View.INVISIBLE);
      VIEWSTATE1 = false;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();
      }
      });
      mRequestQueue.add(jsonObjectRequest);
      }

      public void loadMovieData(List movieDetailsList){
      //Create the adapter using the MovieDetails lists and apply the adapter to the recycler view
      posterAdapter = new PosterAdapter(movieDetailsList, this);
      mRecyclerViews.setAdapter(posterAdapter);
      }

      // This method views changes in the favorites database and updates it's cooresponding recycler view
      public void loadFavoritesData(){
      MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
      viewModel.getMovies().observe(this, new Observer<List<MovieEntry>>() {
      @Override
      public void onChanged(@Nullable List<MovieEntry> movieEntries) {
      Log.d("TAG", "UPDATE FROM THE DATABASE using livedata in viewmodel");
      favoritesAdapter = new FavoritesAdapter(movieEntries, MainActivity.this);
      }
      });

      }


      //This method updates the main view to show the favorites list
      public void showFavsList(){


      mRecyclerViews.setLayoutManager(layoutManager1);
      mRecyclerViews.setHasFixedSize(false);
      mRecyclerViews.setAdapter(favoritesAdapter);
      mErrorMessage1.setVisibility(View.INVISIBLE);
      VIEWSTATE1 = true;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();
      }

      @Override //This method opens the next activity and loads data based on the index passed through from the adapter onClick method
      public void onPosterItemClick(MovieDetails movieDetails) {

      String parcelData = MainActivity.this.getString(R.string.parcel_data);
      Intent intent = new Intent(this, DetailActivity.class);
      intent.putExtra(parcelData, movieDetails);
      startActivity(intent);
      }

      @Override //Override this method to inflate the menu resource
      public boolean onCreateOptionsMenu(Menu menu) {

      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.sort_by, menu);
      return true;
      }

      @Override //Handle clicks on certain menu items. In this case it handles the sorting methods.
      public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();

      if(id == R.id.popular_sort){
      updateUI(popularSortLink);
      return true;
      }else if(id == R.id.rating_sort){
      updateUI(topRatingSortLink);
      return true;
      }else if(id == R.id.favorites_sort){
      // display the favorites list
      showFavsList();
      return true;
      }
      return super.onOptionsItemSelected(item);
      }


      @Override
      protected void onSaveInstanceState(Bundle outState) {
      super.onSaveInstanceState(outState);
      favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);

      //Log.d("TEST", String.valueOf(favoritesState));
      if(favoritesState){
      outState.putParcelableArrayList(FavListKey,favListState);
      }
      }
      }









      share|improve this question
















      I know this question relates to this question
      RecyclerView store / restore state between activities but it is specific to my own problem, maybe you can help. I won't post all the code as there is a LOT of it.



      In the MainActivity below I want follow what what is suggested in that answer, the only difference is that I use SharePreference to distinguish between what view was last on the screen. For some reason it still loads the items for layoutManager on rotation. Not only this, but it does not even save the state of that view, it just resets. I posted all the code from this Activity in the hopes that someone can spot where I went wrong. I can also post the github link if needed. Whole app can not be used unless you have API key described in the github. Please let me know if you need the AndroidManifest or anything else.



      public class MainActivity extends AppCompatActivity implements PosterAdapter.PosterItemClickHandler, FavoritesAdapter.FavoritesClickHandler {

      private PosterAdapter posterAdapter;
      private FavoritesAdapter favoritesAdapter;
      private GridLayoutManager layoutManager;
      private GridLayoutManager layoutManager1;
      private MovieDataBase mDb;
      private SharedPreferences prefs;
      private SharedPreferences.Editor editor;
      private final String FavoriteViewState = "favorites-view-state";
      private boolean VIEWSTATE1;
      private Parcelable favListState;
      private final String FavListKey = "favorites-key";
      private Bundle mBundleRecyclerViewState;



      @BindView(R.id.rv_posters)RecyclerView mRecyclerViews;
      @BindView(R.id.tv_error_message1) TextView mErrorMessage1;
      @BindView(R.id.tv_error_message2) TextView mErrorMessage2;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      ButterKnife.bind(this);
      mDb = MovieDataBase.getInstance(getApplicationContext());

      setRecyclerViews();
      updateUI(popularSortLink);
      loadFavoritesData();

      prefs = PreferenceManager.getDefaultSharedPreferences(this);

      if(savedInstanceState != null){
      boolean favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);
      if(favoritesState) {
      favListState = savedInstanceState.getParcelableArrayList(FavListKey);
      //List<MovieEntry> movies = new ArrayList<>(favListState);
      if(favListState != null) {
      favoritesAdapter = new FavoritesAdapter(favListState, MainActivity.this);
      //favoritesAdapter.setFavorites(favListState);
      mRecyclerViews.setLayoutManager(layoutManager1);
      mRecyclerViews.setHasFixedSize(false);
      mRecyclerViews.setAdapter(favoritesAdapter);
      }
      }
      }
      }


      // This method sets the recycler views for the main screen
      public void setRecyclerViews(){
      // Create the grid layout and apply it to the poster recycler view
      layoutManager = new GridLayoutManager(this,3);
      layoutManager1 = new GridLayoutManager(this,1);
      mRecyclerViews.setLayoutManager(layoutManager);
      mRecyclerViews.setHasFixedSize(true);

      }

      // This method updates the UI based on whether there is a network connection or not.
      public void updateUI(String movieLink){
      if(!isOnline()){
      mErrorMessage1.setVisibility(View.VISIBLE);
      mRecyclerViews.setVisibility(View.INVISIBLE);
      }else{
      mErrorMessage1.setVisibility(View.INVISIBLE);
      mRecyclerViews.setVisibility(View.VISIBLE);
      startApp(movieLink);
      }
      }

      //Information sourced from https://developer.android.com/training/volley/requestqueue
      //09/11/18
      // This method makes a network request using Androids Volley mechanisms to retrieve the json data
      private void startApp(String movieLink){
      RequestQueue mRequestQueue;
      // Instantiate the cache
      Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
      // Set up the network to use HttpURLConnection as the HTTP client.
      Network network = new BasicNetwork(new HurlStack());
      // Instantiate the RequestQueue with the cache and network.
      mRequestQueue = new RequestQueue(cache, network);
      // Start the queue
      mRequestQueue.start();

      JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
      (Request.Method.GET, movieLink, null, new Response.Listener<JSONObject>() {

      @Override
      public void onResponse(JSONObject response) {

      setRecyclerViews();
      mErrorMessage2.setVisibility(View.INVISIBLE);
      mRecyclerViews.setVisibility(View.VISIBLE);
      VIEWSTATE1 = false;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();

      //Parse the JSON string and store in a list of Movie objects
      List<MovieDetails> movieDetailsList = JsonUtility.parseMovieDetailsJson(response);

      // display the data
      loadMovieData(movieDetailsList);
      }
      }, new Response.ErrorListener() {

      @Override
      public void onErrorResponse(VolleyError error) {
      // TODO: Handle error
      Log.i("TAG", error.toString());
      mErrorMessage2.setVisibility(View.VISIBLE);
      mRecyclerViews.setVisibility(View.INVISIBLE);
      VIEWSTATE1 = false;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();
      }
      });
      mRequestQueue.add(jsonObjectRequest);
      }

      public void loadMovieData(List movieDetailsList){
      //Create the adapter using the MovieDetails lists and apply the adapter to the recycler view
      posterAdapter = new PosterAdapter(movieDetailsList, this);
      mRecyclerViews.setAdapter(posterAdapter);
      }

      // This method views changes in the favorites database and updates it's cooresponding recycler view
      public void loadFavoritesData(){
      MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
      viewModel.getMovies().observe(this, new Observer<List<MovieEntry>>() {
      @Override
      public void onChanged(@Nullable List<MovieEntry> movieEntries) {
      Log.d("TAG", "UPDATE FROM THE DATABASE using livedata in viewmodel");
      favoritesAdapter = new FavoritesAdapter(movieEntries, MainActivity.this);
      }
      });

      }


      //This method updates the main view to show the favorites list
      public void showFavsList(){


      mRecyclerViews.setLayoutManager(layoutManager1);
      mRecyclerViews.setHasFixedSize(false);
      mRecyclerViews.setAdapter(favoritesAdapter);
      mErrorMessage1.setVisibility(View.INVISIBLE);
      VIEWSTATE1 = true;
      editor = prefs.edit();
      editor.putBoolean(FavoriteViewState, VIEWSTATE1);
      editor.apply();
      }

      @Override //This method opens the next activity and loads data based on the index passed through from the adapter onClick method
      public void onPosterItemClick(MovieDetails movieDetails) {

      String parcelData = MainActivity.this.getString(R.string.parcel_data);
      Intent intent = new Intent(this, DetailActivity.class);
      intent.putExtra(parcelData, movieDetails);
      startActivity(intent);
      }

      @Override //Override this method to inflate the menu resource
      public boolean onCreateOptionsMenu(Menu menu) {

      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.sort_by, menu);
      return true;
      }

      @Override //Handle clicks on certain menu items. In this case it handles the sorting methods.
      public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();

      if(id == R.id.popular_sort){
      updateUI(popularSortLink);
      return true;
      }else if(id == R.id.rating_sort){
      updateUI(topRatingSortLink);
      return true;
      }else if(id == R.id.favorites_sort){
      // display the favorites list
      showFavsList();
      return true;
      }
      return super.onOptionsItemSelected(item);
      }


      @Override
      protected void onSaveInstanceState(Bundle outState) {
      super.onSaveInstanceState(outState);
      favoritesState = prefs.getBoolean(FavoriteViewState, VIEWSTATE1);

      //Log.d("TEST", String.valueOf(favoritesState));
      if(favoritesState){
      outState.putParcelableArrayList(FavListKey,favListState);
      }
      }
      }






      java android android-studio






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 5 at 20:34







      DNA

















      asked Jan 3 at 4:06









      DNADNA

      37118




      37118
























          1 Answer
          1






          active

          oldest

          votes


















          0















          1. Use onSaveInstanceState(Bundle bundle) instead of onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState).

          2. Don't override onRestoreInstanceState(Bundle savedInstanceState), you're getting Bundle object in onCreate(). Restore your state in there.

          3. Instead of using SharedPreferences to save state in key FavoriteViewState use onSaveInstanceState() and onCreate(). SharedPreferences is overkill in here.

          4. In setRecyclerViews() you're always setting layoutManger as your manager. It may be a problem, it's hard to say without debuging your code.


          EDIT 05.01.2019:



          layoutManager.onSaveInstanceState() which returns Parcelable object dont work like that. You're not supposed to call it in your class, forget about it, it is called internally. In order to restore your view properly, in onSaveInstanceState() you need to save your data list which will be restored later in onCreate(). You can also save there your last clicked position and in your case, information about which layout manager should be set after view will be recreate.






          share|improve this answer


























          • I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

            – DNA
            Jan 3 at 16:21











          • I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

            – DNA
            Jan 5 at 20:35











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54016221%2fhow-to-properly-restore-view-state-on-rotation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0















          1. Use onSaveInstanceState(Bundle bundle) instead of onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState).

          2. Don't override onRestoreInstanceState(Bundle savedInstanceState), you're getting Bundle object in onCreate(). Restore your state in there.

          3. Instead of using SharedPreferences to save state in key FavoriteViewState use onSaveInstanceState() and onCreate(). SharedPreferences is overkill in here.

          4. In setRecyclerViews() you're always setting layoutManger as your manager. It may be a problem, it's hard to say without debuging your code.


          EDIT 05.01.2019:



          layoutManager.onSaveInstanceState() which returns Parcelable object dont work like that. You're not supposed to call it in your class, forget about it, it is called internally. In order to restore your view properly, in onSaveInstanceState() you need to save your data list which will be restored later in onCreate(). You can also save there your last clicked position and in your case, information about which layout manager should be set after view will be recreate.






          share|improve this answer


























          • I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

            – DNA
            Jan 3 at 16:21











          • I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

            – DNA
            Jan 5 at 20:35
















          0















          1. Use onSaveInstanceState(Bundle bundle) instead of onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState).

          2. Don't override onRestoreInstanceState(Bundle savedInstanceState), you're getting Bundle object in onCreate(). Restore your state in there.

          3. Instead of using SharedPreferences to save state in key FavoriteViewState use onSaveInstanceState() and onCreate(). SharedPreferences is overkill in here.

          4. In setRecyclerViews() you're always setting layoutManger as your manager. It may be a problem, it's hard to say without debuging your code.


          EDIT 05.01.2019:



          layoutManager.onSaveInstanceState() which returns Parcelable object dont work like that. You're not supposed to call it in your class, forget about it, it is called internally. In order to restore your view properly, in onSaveInstanceState() you need to save your data list which will be restored later in onCreate(). You can also save there your last clicked position and in your case, information about which layout manager should be set after view will be recreate.






          share|improve this answer


























          • I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

            – DNA
            Jan 3 at 16:21











          • I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

            – DNA
            Jan 5 at 20:35














          0












          0








          0








          1. Use onSaveInstanceState(Bundle bundle) instead of onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState).

          2. Don't override onRestoreInstanceState(Bundle savedInstanceState), you're getting Bundle object in onCreate(). Restore your state in there.

          3. Instead of using SharedPreferences to save state in key FavoriteViewState use onSaveInstanceState() and onCreate(). SharedPreferences is overkill in here.

          4. In setRecyclerViews() you're always setting layoutManger as your manager. It may be a problem, it's hard to say without debuging your code.


          EDIT 05.01.2019:



          layoutManager.onSaveInstanceState() which returns Parcelable object dont work like that. You're not supposed to call it in your class, forget about it, it is called internally. In order to restore your view properly, in onSaveInstanceState() you need to save your data list which will be restored later in onCreate(). You can also save there your last clicked position and in your case, information about which layout manager should be set after view will be recreate.






          share|improve this answer
















          1. Use onSaveInstanceState(Bundle bundle) instead of onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState).

          2. Don't override onRestoreInstanceState(Bundle savedInstanceState), you're getting Bundle object in onCreate(). Restore your state in there.

          3. Instead of using SharedPreferences to save state in key FavoriteViewState use onSaveInstanceState() and onCreate(). SharedPreferences is overkill in here.

          4. In setRecyclerViews() you're always setting layoutManger as your manager. It may be a problem, it's hard to say without debuging your code.


          EDIT 05.01.2019:



          layoutManager.onSaveInstanceState() which returns Parcelable object dont work like that. You're not supposed to call it in your class, forget about it, it is called internally. In order to restore your view properly, in onSaveInstanceState() you need to save your data list which will be restored later in onCreate(). You can also save there your last clicked position and in your case, information about which layout manager should be set after view will be recreate.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 5 at 9:28

























          answered Jan 3 at 7:14









          DawidJDawidJ

          745717




          745717













          • I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

            – DNA
            Jan 3 at 16:21











          • I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

            – DNA
            Jan 5 at 20:35



















          • I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

            – DNA
            Jan 3 at 16:21











          • I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

            – DNA
            Jan 5 at 20:35

















          I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

          – DNA
          Jan 3 at 16:21





          I edited the question with your fixes excluding #3 for now. Please see onCreate, onSaveInstanceState, and onResume. In onResume it gets through both if statements, but "layoutManager1.onRestoreInstanceState(favListState)" does not produce a result of restoring the state. What might I be missing? Please note for #4 I set layoutManager1 in showFavList() method. If I don't set one of them I wont have a view when I load, so this point confuses me. I removed some methods that aren't needed so its easier to read.

          – DNA
          Jan 3 at 16:21













          I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

          – DNA
          Jan 5 at 20:35





          I edited again. Please refer to onSaveInstanceState and onCreate. Still no results. Thank you for your help so far in trouble shooting.

          – DNA
          Jan 5 at 20:35




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54016221%2fhow-to-properly-restore-view-state-on-rotation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          generate and download xml file after input submit (php and mysql) - JPK

          Angular Downloading a file using contenturl with Basic Authentication

          Can't read property showImagePicker of undefined in react native iOS