I have looked around and found variations of this question, but all of the answers seem to be ugly hacks. Is there no easy and proper way to achieve this?
Say for instance I have Activity A, which has a FrameLayout that can hold one fragment at a time. Lets say that when the Activity is first started it loads Fragment A into the FrameLayout, which consists of a ListView. When an item is selected in Fragment A it starts up Fragment B. The way I am currently doing this is by simply hiding Fragment A and then adding Fragment B since this preserves Fragment A's state. I am of course also adding this fragment transaction to the backstack.
So now Fragment A exists on the backstack. Say now I go back to my Android home screen and go to another app. While I am doing this, the Android system decides to destroy my application because the system needs more memory. When I navigate back to my application, how am I supposed to properly restore the state of Fragment B, and Fragment A which is currently on the backstack.
I cannot use setRetainInstance() since it does not work for Fragments placed on the backstack.
Essentially what I am trying to do is restore the backstack to exactly how it was before my application was forcefully closed. So Fragment A should be on the backstack (but not showing), and Fragment B should be currently showing. If I hit the back button, it should properly pop Fragment A off the backstack.
Some notes
Since the application was forcefully closed, it's savedInstanceState != null. Same thing holds for the fragments.
Related
I have a Navigation panel activity. With 5 fragments (Will name it as Fragment1, Fragment2, ...) in menu sections.
Now by Default, activity will display Fragment1.
If user navigate to Fragmentxtz from Fragment1. We will add the fragment on top of Fragment1.
Now user goes to background by pressing home button and open the app from tasks.
Now i know Fragmentxtz onStart will be called. But i see that Fragment1 onStart is also called.
Is this expected behavior ?
As you can see on Android Developers, your fragment will be called at onViewCreated().
https://developer.android.com/guide/components/fragments#Creating
The View has to be updated in case you changed the system language or something like that.
Providing a bit more context to what might be happening here.
If both of your fragments are added e.g. via FragmentTransaction.add() both of them will have onCreateView() called when the layout is restored for the user as Robert pointed out. From the system's point of view all of those fragments are relevant to the user and would be shown simultaneously.
If on the other hand you add fragments via FragmentTransaction.replace() only the topmost fragment on the back stack will receive the onCreateView() call. This can also be achieved by doing an add and remove of the old fragment. If you make this transaction reversible by the back stack after pressing the back button your previous fragment would receive the appropriate lifecycle callbacks.
I have a Fragment stack, which fragments are added to (not replaced). The problem is, because of memory issues, I don't want to have more than a specific amount of fragments in the stack. Suppose I have added fragments A, B, C, D to the stack. Now that I want to add the Fragment E, I want the A to be removed, using this piece of code:
fragmentManager.beginTransaction().remove(fragmentA).commit()
I get fragmentA using findFragmentByTag() and I am sure fragmentA exists and is in the stack. But this has no effect, and doesn't remove fragmentA.
What's wrong you think?
Is it possible to remove a fragment from bottom of the stack?
I'm confused in a fundamental Android fragment lifecycle.
When I press back, none of my nested fragments are saved and the app recreates everything in a parent activity. These nested fragments are inside viewpagers.
Now, if I press the menu button, and come out of the app, it is stored.
Why does it happen? And how do I ensure that even if the user comes out of the app, by pressing back, the nested fragment states are saved, and restored when the user opens the app again.
There is a fragment state pager adapter for viewpager's to save the state of fragments. But you can still not change the fragment life cycle which is dependent on activity life cycle. So if an activity's on destroy is called, all its fragments will be destroyed. So, this might be your case.
I am developing an app, where fragments are changing in the container of one Activity. I am using FragmentTransaction.replace(R.id.container, fragment, tag) to switch between fragments.
All fragments has setRetainInstance(true). When I press Home button and go back to app everything is ok, but when I turn on developers option "Don't keep activities" and do the same, I end up with "clean" activity where there is only the first (initial) fragment presents. In other words, after Activity is reinitialised all fragments are lost.
How can I avoid that and save fragments state?
I would like my fragments backstack to have a single instance of every fragment added to it. In other words, when I recall a fragment already instantiated (and added to the backstack) without popping it from the backstack (i.e. with a FragmentTransaction.replace by passing its tag name) I would like it to have it ONLY on the top of the FragmentManager's backstack. I can use FragmentTransaction.addToBackstack, but this cannot delete previous fragment references and I don't want to pop the backstack to erase the previous reference, otherwise I lose part of the history I still would like to retain.