I want to save my fragment with recycler view, to restore it whlie screen rotate. I was looking for instructions in the net and I get:
In my Fragment
private Parcelable recyclerViewState;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
list.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
recyclerViewState = layoutManager.onSaveInstanceState();
}
in my Activity
//onCreate
if (savedInstanceState != null) {
getSupportFragmentManager().getFragment(savedInstanceState, LIST_USERS_FRAGMENT);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().getFragment(outState, LIST_USERS_FRAGMENT);
}
I was debbuging and it looks fine, however while I rotate my screen I get blank fragment, with no recycler view. Could You help me investigate why it's happening ?
The default behavior in Android is destroying all the attached fragments on configuration changes. To bypass fragment recreation you should use setRetainInstance(true) in the OnCreate callback of the fragment.
There are a different options to handle the orientation changes:
Lock screen orientation
<activity
android:name="com.example.test.activity.MainActivity"
android:screenOrientation="portrait"/>
Prevent Activity to recreated
<activity
android:name="com.example.test.activity.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"/>
Save basic state
public class MainActivity extends Activity{
private static final String SELECTED_ITEM_POSITION = "ItemPosition";
private int mPosition;
#Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
// Save the state of item position
outState.putInt(SELECTED_ITEM_POSITION, mPosition);
}
#Override
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Read the state of item position
mPosition = savedInstanceState.gettInt(SELECTED_ITEM_POSITION);
}
}
Save complex objects
Override
onRetainNonConfigurationInstance()
getLastNonConfigurationInstance()
After API level 13 these methods have been deprecated in favor of the more Fragment’s setRetainInstance(boolean) capability, which provides a much cleaner and modular means of retaining objects during configuration changes.
Related
I have a little project, one activity and two fragment. I have started from the "Bottom Navigation Activity" sample on a new projet.
The I use the Android Annotations (https://github.com/androidannotations/androidannotations/wiki) for injecting my fragment, It display correctly but when I rotate, I loose all my information and the app display the first fragment, even if I displayed the second one. I tried to save my data, from an edit text with a Bundle object, in the "onSaveInstanceState" method, I get back it in the "onActivityCreated" or in the "onCreate" method but after their method were re-call and my data desappear.
I don't know how to save which fragment was displayed and how re-displayed it with the android annotations.
In my Activity class I have those methods :
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
And in my main fragments :
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(dpdEditText != null){
rttNumberTemp = rttEditText.getText().toString();
outState.putString("rttNumberTemp", rttNumberTemp);
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(Tag, "onActivityCreated");
if(savedInstanceState != null){
Log.d(Tag, "onActivityCreated if");
updateEditText(rttEditText,savedInstanceState.getString("rttNumberTemp"));
}
}
So my question is how can I save my fragment, and its data and which fragment is displayed ?
I finally find my mistake. In my main activity I have the following method :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
So the program call the view by the injection and call it again with the setContentView. So I update the method like that :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
I went trough a famous post in SO, Maintain/Save restore scroll position
but does not help me at all.
I have a ListView inside a Fragment, if I change the orientation, I would like that saveInstance Bundle will save my position.
I have
private static final String LIST_STATE = "listState";
private Parcelable mListState = null;
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mListState = listView.onSaveInstanceState();
outState.putParcelable(LIST_STATE, mListState);
}
and does not matter if I put in OnCreateView or in onActivityCreated the following code
if(savedInstanceState!=null) {
mListState = savedInstanceState.getParcelable(LIST_STATE);
listView.onRestoreInstanceState(mListState);
the up position of the list is not restored at all.
I can easily see from the debug in Bundle that the debug recognize in the Bundle the position,
AbsListView.SavedState{3d7562e0 selectedId=-9223372036854775808
firstId=25 viewTop=-38 position=5 height=717 filter=null
checkState=null}
I even tried to extract from the Bundle this position in an isolated way instead of all the values, but without success.
add following code inside fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
Found it!
The solution is
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mPosition2=listView.getFirstVisiblePosition();
if(mPosition2!=0) {
mPosition = mPosition2;
}
if (mPosition != ListView.INVALID_POSITION) {
outState.putInt(SELECTED_KEY, mPosition);
}
}
and in onCreateView
if (savedInstanceState != null && savedInstanceState.containsKey(SELECTED_KEY)) {
mPosition = savedInstanceState.getInt(SELECTED_KEY);
}
finally I have a loader that query a content provider at end of onLoadFinished( but you can put you just where you need)
if (mPosition != ListView.INVALID_POSITION) {
listView.setSelection(mPosition);
I have also tried listView.smoothScrollToPosition(mPosition)
but is not working at the moment, but never mind it works really well to me.
I have the following (to avoid checking if a fragment is being created newly or just being recreated)
#Override public void onActivityCreated(Bundle args) {
super.onActivityCreated(args);
if (this.getArguments() != null) args = this.getArguments();
// rest of fragment loading goes here
}
Not sure what you are trying to do never seen budle values being overwritten.
If you want some values to be availbale inside fragment pass those values to activity and inside fragment call getActivity().getIntent().getExtra(
Otherwise have a look at code below if want save some fragment data if fragment is destroyed
Inside fragment in onCreate method check if savedInstanceState is null or not
#Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
//fragment recreated
}
}
Save data as follows
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (jsonObject != null) {
outState.putString(Constants.JSON, jsonObject.toString());
}
}
i have a problem with my app. if i click the button to stop the ProgressBarIndeterminate in actionbar, when i rotate the screen it reappear. can i stop it forever? thanks
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
setProgressBarIndeterminateVisibility(true);
}
public void test(View v) {
setProgressBarIndeterminateVisibility(false);
}
sorry for my english
When you rotate your screen, the Activity gets created again (onCreate will get invoked again), so you will call setProgressBarIndeterminateVisibility(true) which will make it reappear.
To keep track of whether or not you've clicked the stop button, you will need to save the state somehow (consider implementing onSaveInstanceState and then retrieving the stored value in onCreate, or saving the state to a shared preference/database).
onSaveInstanceState --> invoked when your Activity is torn down due to the rotation
private boolean showProgressBarVisibility = true; //always show the first time
#Override
public void onCreate(Bundle savedInstanceState){
if(savedInstanceState != null && savedInstanceState.containsKey("user3744384_pressed_the_button"){
showProgressBarVisibility = false
}
setProgressBarIndeterminateVisibility(showProgressBarVisibility);
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("user3744384_pressed_the_button", true);
}
do something like this in onCreate:
if(savedInstanceState !=null){
setProgressBarIndeterminateVisibility(false);
}
but you should also save the state in public void onSaveInstanceState(Bundle ...).. research on how activities save their state.
when orientation changes android kills your activity and onCreate is called.. you can save your app state and restore it.
override this method to save state
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(key, yourstatevariable);
}
and get your state variable in onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
if (savedInstanceState != null) {
String yourstatevariable = savedInstanceState.get(key);
}
}
I want to save the state of my FragmentPagerAdapter so I can reuse it after the orientation of the screen changed. Unfortunately the method saveState returns always null.
My Adapter consists of an ActionBar with two Fragments.
Here ist my method call
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(FRAGMENT, viewPager.getCurrentItem() + 1);
outState.putParcelable(ADAPTER, fragmentTabAdapter.saveState());
super.onSaveInstanceState(outState);
}
But the Adapter in outState is always null. I don't understand why. Is there something special I missed about the use of saveState?
Hope you can help me!
this example works if the fragment is not destroyed
private int pageID;
#Override
public void onPause() {
super.onPause();
pageID = mViewPager.getCurrentItem(); // 1 save
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mViewPager.setCurrentItem(pageID, false); // 2 load
}