Replaced fragment lost after orientation change Android - android

I have an activity which loads a fragment (say Fragment1) in onCreate. When the user presses a button in Fragment1, I replace Fragment1 with a new fragment, say Fragment2. The problem is that on changing orientation while in Fragment2, the activity is recreated and shows Fragment1
instead of Fragment2. (because I create Fragment1 in onCreate)
How can I stick to Fragment2 and also retain its state on orientation change?
Thanks

When a fragment transaction occurs, assign a variable so you know which fragment is being created. Then override OnSavedInstanceState and pass your variable into the bundle.
Then on orientation change, onCreate will be called and you can retrieve your variable from the savedInstanceStateBundle. You can then choose which fragment will be 'loaded' in the onCreate.

Related

Fragment recreation on back from another activity

I have two activities, A and B.
Activity A, has one fragment F, added dynamically via a transaction. From F, I start activity B (F.getActivity.startActivity(intent)). When I press the back button, F gets recreated. Can I avoid that?
If not, I understand I can save the fragment state, but the savedInstanceState bundle is always null. I found you must set an id in the XML, but as the fragment is dynamically created, I don't know how to set it.
Thanks.
you can manage it by adding fragment to backstack by below code
fragmentTransaction.add(R.id.containerView, fragment);
fragmentTransaction.addToBackStack("test");
and pop back the fragment state by below one
fragmentManager.popBackStack("test", FragmentManager.POP_BACK_STACK_INCLUSIVE);
hope this will be helpful.

Which lifecycle methods are called when a fragment is popped off backstack

I have FragmentA and FragmentB.
I added FragmentA to an Activity using the add (not replace) fragment transaction. A button in FragmentA makes a callback to it's Activity which then makes an add fragment transaction to add FragmentB.
I update the title of the ActionBar with the value of a variable (which is fetched online) in FragmentA and FragmentB.
After the fragment transactions I outlined above, if I'm in FragmentB and I press the back button (now I'm in FragmentA), the title of the ActionBar is still that of FragmentB.
So I wanted to know which lifecycle methods are called on FragmentA when I'm coming from FragmentB so I can update the Actionbar from there.
I don't know if there is a method that is called when backstack is popped, but what you can do is overwrite onBackPressed in your Activity class that contains the fragments, call fragmentManager.popBackStackImmediate. This method returns a boolean, if it's true, then you went from fragmentB to fragmentA (or to any other previous fragment). You are in your activity class, so you can update your ActionBar anyway you'd like.
One more thing, if fragmentManager.popBackStackImmediate is true, don't call super.onBackPressed()!!!
onStart() method is clearly the adapted one. When comming from backstack, it will always be called.

Fragment and Fragment on BackStack

CONSTRUCTION
Activity A holds Fragment A that is able add Fragment B on backstack.
PROBLEM
Fragment B holds Views generated via API response.
State of these Views is what I need to be able to recreate after rotation or when going back to Fragment A by using onBackPressed and lunching Fragment B again.
I've read quite some of the topics on SO about Fragments in backstack and I am aware of their inability to retain instance.
What should I do to achieve such outcome?
Fragments on backstack can always retain instance if you save it. An Activity or a Fragment on a backstack in simply in a paused state. So you want to save the data/variables in the onSaveInstanceState method for that class (you will be overriding it).
Now to restore from the saved state you would have noticed that the onCreate, onCreateView for Activity, Fragment, respectively, have a Bundle savedInstanceState parameter being passed in. This is where you saved your state in the previous step, thus, you can add
if (savedInstanceState != null) {
//TODO: restore the state
}
to your onCreate/onCreateView method and you should be good to go.

Empty savedInstanceState Bundle when restoring a Fragment after double Rotation in replacing Fragment

lets call them Fragment A and B. Fragment B is just a detailed view for A which replaces the Fragment A upon a click of a Button in Fragment A.
The replacement code:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, new DetailFragment());
transaction.addToBackStack(null);
transaction.commit();
When I now rotate the screen in Fragment B once and press Back the old Fragment A gets restored without any problems (it restores it state in onActivityCreated with the savedInstanceState Bundle).
Now to the fun part...
When I rotate the screen in Fragment B more than once and press Back I get a NullPointerException because int[] data = savedInstanceState.getIntArray(STATE_DATA); in onActivityCreated returns null.
How can I fix this behavior? The only other way I though of was through permanent Storage(Preference or DB) but that seems very inappropriate for the use case.
edit/additional info: The bundle itself is not null, it's just empty
Ok I found the answer:
The following methods from Fragment A get called on rotation change while Fragment B is active:
onSaveInstanceState(), onAttach() and onCreate()
because I am restoring my state in onActivityCreated (which is actually recommended by the sdk!) I lose my variables stored in the bundle after the first rotation because they never get loaded into the local variables that then would be stored on the next onSaveInstanceState. Therefore those values are null when I try to retrieve them after the second rotation.
Solution: Restore the variables in onCreate() so that they are available when onSaveInstanceState is called again.

Fragment Rotation not restoring current fragment

I have a fragmentactivity that starts on Fragment A then can be change to Fragment B. If i am on Fragment B and i rotate my device. It loads the original Fragment A not Fragment B. I am Loading both Fragment A and B pragmatically. I thought android was supposed to save which Fragment i was on automatically i am not overriding onSaveInstanceState
This is how i am loading the fragments
FragmentTransaction t = this.getSupportFragmentManager()
.beginTransaction();
t.replace(R.id.fragholder, new MainFragment());
t.commit();
When you rotate your device, it destroys your Activity and recreates its. So assuming Fragment A is the default Fragment, then it is logical that it would load that when the Activity is recreated. So you would need to override onSaveInstanceState to store which Fragment is visible and then reload that Fragment in onCreate.
Reference to relevant Activity Lifecycle doc:http://developer.android.com/training/basics/activity-lifecycle/recreating.html
Just add android:configChanges="orientation|screenSize" to your manifest and android takes care of everything for you

Categories

Resources