I have FragmentX in a ViewPager. FragmentX has EditText's in it and a Button. The user presses the Button and FragmentY replaces FragmentX. The user then presses back and FragmentX has lost all of its input from the user.
How do you either:
a) Save the data in FragmentX before FragmentY appears then FragmentY is replaced by FragmentX retrieve the data and fill in the EditText's in FragmentX
(please don't reply with OnSaveInstanceState, as this does not work unless the Fragment is destroyed, which in this case it is not)
b) somehow keep the data in FragmentX so it is there when we go back to FragmentX from FragmentY..
Any suggestions?
Using addToBackStack() might help in your case.
If you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment lifecycle.
So if you want to store state you should use instance variables and not rely on onSaveInstanceState().
Check this out: Maintaining fragment states
I am now saving the data in FragmentX to SharedPreferences and overriding onBackPressed in the Activity, and have created a function in the Activity called popFromBackstack where the popBackStack() occurs.
In the functions in my Activity where i replace my Fragments i am now saving the data in FragmentX into SharedPrefs before the replace. I am also checking after the replace if the new Fragment is FragmentX and, if it is, i am filling the data into FragmentX from SharedPrefs.
I am also saving the data from FragmentX in onBackPressed in my Activity (if the current fragment is FragmentX), incase the user presses the back button.
I have also created a public static activity called popBackStack() in my Activity which i call from Fragments to pop the backstack. I am also saving the data from FragmentX here (if the current fragment being popped is FragmentX). Once the Fragment being popped is popped i am checking if the new Fragment is FragmentX, and filling in the data if it is...
Long winded approach but i couldn't figure out any other reliable way. This is working perfectly.
I suggest following guidelines that Google provides and implement an interface declared in your Fragment and save the Bundle or whatever object you want in the activity. Then, in your newInstace() static factory method pass that Bundle and recreate data as usual. Since you are using a ViewPager and it will always render the second fragment before the button is pushed (I assume your second fragment is in another tab) you still need to manage it via an interface. When the back button is pressed, the data will still be there, unless it is destroyed, and you still need to implement onSaveInstaceState() for that matter. You can also use setRetainInstance(boolean retain). See here for more details
Related
I have two fragments,
fragmentA in foreground
now I show fragmentB with FragmentTransaction.add(id, Fagment), (not .replace) so the fragmentA is still alive, with fragmentB on top of it,
now I use back button, here the fragmentB is destroyed, leaving fragmentA visible,
at this moment, how would I know that fragmentA has returned to the "foreground", ie onResume,
note that onResume is not called, due to FragmentTransaction.add(id, Fagment), in other words, fragmentA doesn't go onPause when fragmentB is shown
thank you very much for your help
If you want to know when fragment A becomes visible again, you can first hide it in the fragment transaction that creates fragment B:
fragmentTransaction.add(id, fragmentB).hide(fragmentA).addToBackStack(null);
Then in Fragment A, override onHiddenChanged:
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
// Handle visibility changed. Note this method is called only when the state is changed.
}
When the back button is pressed, the fragment transaction will be reversed and the fragment's state will be changed to visible. One thing you have to watch out for: I've noticed that the hidden state isn't preserved between activity rotation so you'd have to perform your own bookkeeping in onSaveInstanceState. I do something similar to what you're asking since in my case the fragment views are expensive to recreate.
Before doing this though, you might want to consider handling your fragments another way, like with .replace() instead of .add(). If your fragment is completely hidden by the new fragment, then maybe you don't need to keep it around, and you can let the fragment manager bring it back once the user hits the back button. That way, you can just use the normal lifecycle functions like onPause and onResume.
Let me explain my application first.
I have an activity and fragments in it. I'm opening fragmentA onCreate of application. In fragmentA,before i open fragmentB by using support fragment manager's replace() method, i call a webService for some json datas.
Then i open fragmentB with these json datas. After i opened the fragmentB, i want to turn back to fragmentA by using device's default backbutton, and i don't want to handle backButtonPress(). Just go back to previous fragment. My app does this.
Here is the question. When i press back button, my fragmentA calls the service again and it affects the user to wait. But how can i just turn to the previous fragment ?
I am looking for the best solution to turn previous fragment.
I'm trying to understand some odd behavior. I have an ActivityA that calls a method in onCreate() to add FragmentA to R.id.fragment_container. Inside FragmentA I have a button that attaches FragmentB by using ActivityA's fragment manager (getActivity().getSupportFragmentManager()) and replacing the R.id.fragment_container and I also add it to the backstack. I also have another button that starts a new ActivityB.
When I navigate back from ActivityB I get: ActivityA onResume(), FragmentA onResume(). But when I navigate back from FragmentB I get: FragmentB onCreateView(), FragmentB onActivityCreated() then the 2 onResume().
So my questions is...why is the view state saved when a new activity is launched and not when the fragment is replaced and reattached. It looks much better to just restore that state rather than recreate the views and fetch that data again. This seems like opposite behavior from what I would expect so I'm clearly missing some fragment state saving/restoration step or something. It seems like the activity is just pausing FragmentA (and ActivityA) when ActivityB is launched and restoring it on back pressed but when FragmentB is attached FragmentA gets completely destroyed. I'm sure there's a way to prevent this I just can't seem to figure it out. Thoughts?
Just below your question are four tags android,android-fragments,android-lifecycle& android-navigation .Put your cursor over it for a while a black box will pop up . click on info tab and you will get best links to study that topics along with links to books .
Hope this will help you
Scenario:
I have a single Activity in which I have multiple fragments and I'm replacing one fragment with another using fragment transaction and add them to BackStack. I am doing JSON parsing and network related task on some fragments.
Problem:
My problem is that after replacing the fragment when I press back button to nevigate to last fragment the onStart and onActivityCreated methods called again. My code in these events execute each time I navigate to that fragment by using back button
But
Any value in EditText remain same in even after replacing the fragment and coming back to it using back button.
Why onStart and onActivityCreated executed each time?
Is there any method where I can put my code which do not execute after coming back to fragment?
UPDATE
Basically I want to set a button text once fragment is created. User can change that text. but when I return back to that fragment the users value change with the default text which I set on fragment creation time.
Thanks
You can put your code to run only one time at fragment creation in onCreate() of fragment..
onCreate()
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
See the life cycle of fragment.
You can also get more details here
I have got loader in fragment and it loads data on background. After data are loaded, I fill edittexts with that informations. Problem is that if user changes something in edittexts and rotate screen, onLoadFinished is called again and edittexts are replaced with loaded information. I solve this by adding help variable, if data was already loaded .. But when i replace this fragment with other, rotate screen back and forth and press back button, edittexts are empty. Fragment is set to retain instance true. It looks like views lost its state when fragment is on backstack. Anyone familiar with this?
You shouldn't use the retain state.
But the proper way to do so it to save the save using the Bundle and restore it when you recreate the activity (onCreate Bundle is not new).
Please review the link I've sent you it includes a very specific example.
from the android dev guide:
To properly handle a restart, it is important that your activity
restores its previous state through the normal Activity lifecycle, in
which Android calls onSaveInstanceState() before it destroys your
activity so that you can save data about the application state. You
can then restore the state during onCreate() or
onRestoreInstanceState().
Android Rotation Change