Reputation: 6426
I am working on an application and there is one specific thing that is bothering me. Let's just say I have one activity and 2 fragments.FragmentA and FragmentB and FragmentA gets attached when activity starts.
I want to save the fragment data and fragment state when orientation changes occur.I have successfully saved fragment data using OnSavedInstanceState
method. Now I want to save fragment state in the activity so that if orientation change occurs I want to be on the fragment I was (in my case either FragmentA or FragmentB depends on which was showing before config changes occur).
This is how I am saving the fragment state in the Activity:
@Override
protected void onSaveInstanceState(Bundle outState) {
// Save the values you need into "outState"
super.onSaveInstanceState(outState);
outState.putLong(SS_DATE, userDate.getTime());
android.support.v4.app.FragmentManager manager = getSupportFragmentManager();
Fragment currentFragment = this.getSupportFragmentManager().findFragmentById(R.id.content_container);
manager.putFragment(outState, "currentFragment", currentFragment);
}
And this is how I am retrieving on which fragment I was when the orientation change occurred:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
FragmentManager manager = getSupportFragmentManager();
@SuppressLint("CommitTransaction")
FragmentTransaction transaction = manager.beginTransaction();
if (savedInstanceState != null) {
Fragment MyFragment = (Fragment) manager.getFragment(savedInstanceState, "currentFragment");
if (MyFragment instanceof FragListStudentsAttendance) {
Log.v("onRestore", FragListStudentsAttendance.TAG);
}else if (MyFragment instanceof FragGetClassesForAttendance){
Log.v("onRestore", FragGetClassesForAttendance.TAG);
if(MyFragment!=null) {
mFragGetClassesForAttendance = (FragGetClassesForAttendance) MyFragment;
}else{
mFragGetClassesForAttendance = new FragGetClassesForAttendance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// mFragGetClassesForAttendanceNew.setRetainInstance(true);
// transaction.replace(R.id.content_ssadmin_container, mFragGetClassesForAttendanceNew, "FragGetClassesForAttendance").addToBackStack(null);
transaction.add(R.id.content_ssadmin_container, mFragGetClassesForAttendance, FragGetClassesForAttendance.TAG);
//transaction.replace(R.id.newEnrollmentMainContainer, mFragNewEnrollmentResults).addToBackStack("FragNewEnrollments");
transaction.commit();
mFragGetClassesForAttendance.setDate(userDate);
}
}
}
}
Now Scenario 1: If I am on fragment A and I rotate the device every thing works fine as it should. Like fragment have web services which loads the data into listview so I check if data exist then there is no need to run the web service and that working for now
Scenario 2: If I am on fragment B and orientation change occurs everything works fine as it is supposed to be on fragment B. Now When I press back button Fragment A gets called again and all the data also comes from service. I think this shouldn't happen because it was supposed to be in BackStack and it's data was saved. So what Should I do now here?
Scenario 3: On FragmentB I have noticed that when I rotates the device the saveInstanceState function of FragmentA also gets called. Why it is so? where as I was replacing the FragmentB with FragmentA ?
Some Confusions:
Let me talk about some of the confusions also , maybe someone clear it to me although I have searched and read a lot about fragment and activity life cycle, Actually I want to save the data per activity and fragment on device rotation. I know how to do it with activity(how to save states) so I also know how to do it in the fragment (save state of fragment views) now I am confused how to tell activity which fragment was showing and which to go after config changes(rotation) ? also what happens to FragmentA if I am on FragmentB Does its get attach and detach again and again in background?
Upvotes: 0
Views: 2337
Reputation: 2082
I got your problems and confusions. I think the life cycle of fragment is confusing you. and indeed it will confuse you.
You need to learn different situations. 1. Fragment Life cycle when it is in foreground (attaching and detaching with activity) . Please keenly observe all the methods that will call i.e OnSaveInstance,onCreateView,OnDestroyView,onDestroy 2. Fragment life cycle when it is in background (observe the methods stated above) 3. Fragment life cycle when it is added to backstack (and not in foreground)
I am quite sure you are confused with the point number 3. As when the fragment is added to backstack it never gets destroy. So rotating device twice will set the ffragment data to null. I think you are restoring data on ActivityCreated or on onViewCreated ,
Ill suggest you to restore the fragment data in the oncreate. this will work for you when your fragment is coming back to foreground from the backstack .
Example
private List<String> mCountries;</pre>
@Override
public void onCreate(Bundle savedInstanceState)
{
if (savedInstanceState != null)
{
// Populate countries from bundle
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_countries, container, false);
if (mCountries == null)
{
// Populate countries by calling AsyncTask
}
return view;
}
public void onSaveInstanceState(Bundle outState)
{
// Save countries into bundle
}
Hope this will clear your confusions.
Upvotes: 1