How to use onSaveInstanceState and onRestoreInstanceState to prevent losing checkbox and radiobutton selections
Use something like this: (adjust to your own code)
public class YourActivity extends AppCompatActivity {
private static final String CHECKBOX_CHECKED_KEY = "is_checkbox_checked";
private CheckBox myCheckBox;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
myCheckBox.setChecked(savedInstanceState.getBoolean(CHECKBOX_CHECKED_KEY));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState)
outState.putBoolean(CHECKBOX_CHECKED_KEY, myCheckBox.isChecked());
}
}
You will need to define different keys for each CheckBoxe's state you want to save.
Where use onSaveInstanceState and onRestoreInstanceState methods?
1 - The first article implements these methods on a layoutManager!?
So, I'm using a default GridLayoutManager, so to implement save and
restore instance in the GridLayoutManager I should create my own class
extending the default class?
If you look at both the article and the SO post they do not implement anything inside the LayoutManager
, they just use methods that already exist.
If you look in the documentation page for the GridLayoutManager there are already both a onSaveInstanceState()
and a onRestoreInstanceState (Parcelable state)
methods (these two methods are the "convenient API" the blog mentions at the start).
As I'm sure you've noticed GridLayoutManager
inherits from LinearLayoutManager
official documentation of LinearLayoutManager.onSaveInstanceState():
Called when the LayoutManager should save its state. [...] Returns:
Parcelable Necessary information for LayoutManager to be able to restore its
state
official documentation of LinearLayoutManager.onRestoreInstanceState (Parcelable state)
Very incomplete but you can tell that it uses the same Parcelable
parameter returned by LinearLayoutManager.onSaveInstanceState()
2 - I can implement these methods in the layoutmanager regardless of
implementing them in the activity?
To be clear: no need to re-implement the LayoutManager. I don't see why you would need to do that, the methods are there and ready to use.
The Activity methods of the same name are what you need to implement.
3 - Where is the correct place to implement these methods? or is there
a official answer to the question: "How restore the state of a
recyclerview?"
The correct place to do this is the Activity's lifecycle methods, these will be called at the appropriate times to save and restore your LayoutManager
state.
Quoting the SO answer you mentioned:
//---> this is the Activity's onSaveInstanceState
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
// Save list state
mListState = mLayoutManager.onSaveInstanceState();
state.putParcelable(LIST_STATE_KEY, mListState);
}
//---> this is the Activity's onRestoreInstanceState
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
// Retrieve list state and list/item positions
if(state != null)
mListState = state.getParcelable(LIST_STATE_KEY);
}
//---> this is the Activity's onResume
@Override
protected void onResume() {
super.onResume();
if (mListState != null) {
mLayoutManager.onRestoreInstanceState(mListState);
}
}
I haven't seen any official documentation about specifically restoring the RecyclerView/LayoutManager state but the lifecycle subject is a very important one in Android. I believe that after fully understanding this one can make the right decisions regarding specific use-cases.
Hope this helps ;)
How to use onSaveInstanceState and onRestoreInstanceState methods with fragments?
You will want to override the onSaveInstanceState
method of your activity so that you know when the state needs to be saved. Then you will also need to update your onCreate
method to check if the savedInstanceState
is null
. If it is null
then the activity hasn't been initiated. This is the example for your MainActivity
class, and you can go from there:
MainActivity.java
public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {
private ArrayList<String> todoItems;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
todoItems = new ArrayList<String>();
} else {
todoItems = savedInstanceState.getStringArrayList("todoItemTag");//the tag must match what the variable was saved with
}
FragmentManager fm = getFragmentManager();
ToDoListFragment listToDo = new ToDoListFragment();
listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
listToDo.setListAdapter(adapter);
}
public void OnToDoAdded(String newToDo) {
todoItems.add(newToDo);
adapter.notifyDataSetChanged();
}
//Saving the instance by overriding this function
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("todoItemTag", todoItems);//it would be advised to make the tags a static final String
}
Hopefully this helps!
PS: I don't think the onRestoreInstanceState
method is really necessary. I guess I have never used it before. I believe that you should be able to provide the same functionality with the null
check in the onCreate
method.
When exactly are onSaveInstanceState() and onRestoreInstanceState() called?
Per the documentation:
void onRestoreInstanceState (Bundle savedInstanceState)
This method is called between
onStart()
andonPostCreate(Bundle)
.void onSaveInstanceState (Bundle outState)
If called, this method will occur after onStop() for applications targeting platforms starting with Build.VERSION_CODES.P. For applications targeting earlier platform versions this method will occur before onStop() and there are no guarantees about whether it will occur before or after onPause().
Using of onRestoreInstanceState
It's not a duplicate...
Ok.
Earlier I was in need to destroy some other activity by any way when the app is minimized.
So I used android:noHistory
.
And of course I have created "Login" activity with copy-paste and forgot to delete noHistory
.
Related Topics
How to Use a Compound Drawable Instead of a Linearlayout That Contains an Imageview and a Textview
Android: Wrap_Content Is Not Working with Listview
Check If Battery Optimization Is Enabled or Not for an App
How to Show Multiple Markers on Mapfragment in Google Map API V2
How to Get Current Flavor in Gradle
Preventing Status Bar Expansion
What Will Happen to the Sharedpreferences on Update an Android App
Android: How to Get a Radiogroup with Togglebuttons
How to 'Gettopactivity' Name or Get Currently Running Application Package Name in Lollipop
How to Find MAC Address of an Android Device Programmatically
Custom Info Window Adapter with Custom Data in Map V2
Emulator in Android Studio Doesn't Start
How to Set Multiple Alarms Using Alarm Manager in Android
Java.Lang.Outofmemoryerror: Bitmap Size Exceeds Vm Budget