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);
}
}
}