6

I have 4 button to replace fragment in activity [fragment A , fragment B , fragment C , fragment D] and then I replace fragment A to activity and I change value in fragment A after that I replace fragment B to fragment A and replace fragment C to fragment B . But I want to replace fragment A to fragment C . How to save state in fragment A.

Code when I commit fragment

  private void beginFragmentTransaction(BaseFragment fragment) {
    String tag = fragment.getClass().getName();
    currentFragmentTag = tag;

    boolean fragmentPopped = getChildFragmentManager().popBackStackImmediate(tag, 0);

    if (!fragmentPopped) {
        getChildFragmentManager().beginTransaction()
                .replace(R.id.container, fragment, tag)
                .addToBackStack(tag)
                .commit();
    }

}

Diagram to replace

fragment A -------> fragment B

fragment B -------> fragment C

fragment C -------> fragment A

PS. I don't want to use back button to back to fragment A , I want to replace fragment A and restore data in the first commit.

Community
  • 1
  • 1
  • 1
    In order to save the Fragment state you need to implement onSaveInstanceState(): "Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated. You can save the state during the fragment's onSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), or onActivityCreated(). – Sudheesh R Jun 11 '17 at 05:30
  • I try to use onSaveInstanceState() , it's not call this fuction and I check bundle in onActivityCreated() when I replace this fragment again, bundle is null. @SudheeshR – Wuttipong Khemphetjetsada Jun 11 '17 at 05:37
  • share your code, where you using bundle. – Sudheesh R Jun 11 '17 at 05:40
  • @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log.d("BEST33", "onSaveInstanceState index " + index); index = 1; outState.putInt("index", index); } – Wuttipong Khemphetjetsada Jun 11 '17 at 05:41
  • @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if(savedInstanceState!=null) { index = savedInstanceState.getInt("index", 0); Log.d("BEST33", "index " + index); }else{ Log.d("BEST33", "save state null"); } } – Wuttipong Khemphetjetsada Jun 11 '17 at 05:42
  • 1
    ok, you have to keep the `fragment details` in bundle every time you load a `fragment`. Try that way. – Sudheesh R Jun 11 '17 at 05:45
  • 1
    also should keep existing fragments in array or something... – Sudheesh R Jun 11 '17 at 05:46
  • 1
    You can also try this : Use OnDestroyView() of the fragment and save the whole object inside that method. Then OnActivityCreated(): Check that if object is null or not(Because this method calls every time). Now restore state of an object here. – Sudheesh R Jun 11 '17 at 05:47
  • Ok , I know , my mistakes . I change replace fragment to this way getChildFragmentManager().beginTransaction() .replace(R.id.container, fragment, tag) .addToBackStack(tag) .commit(); – Wuttipong Khemphetjetsada Jun 11 '17 at 05:47
  • How to save state in OnDestroyView(). onSaveInstanceState(bundle) ? – Wuttipong Khemphetjetsada Jun 11 '17 at 05:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146346/discussion-between-sudheeshr-and-wuttipong-khemphetjetsada). – Sudheesh R Jun 11 '17 at 05:54

3 Answers3

6

Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null.

FYI : this is a sample code. Just for your reference.

public class MainFragment extends Fragment {
private String title;
private double rating;
private int year;

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);

savedInstanceState.putString(TITLE, "Gladiator");
savedInstanceState.putDouble(RATING, 8.5);
savedInstanceState.putInt(YEAR, 2000);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

title = savedInstanceState.getString(TITLE);
rating = savedInstanceState.getDouble(RATING);
year = savedInstanceState.getInt(YEAR);
}
}

FYI : This really a good thread check this also Once for all, how to correctly save instance state of Fragments in back stack?

Sudheesh R
  • 1,767
  • 3
  • 23
  • 43
1

If you want to save the state of previous tabs and don't want to refresh/recreate view use this code and change the value according to the tabs limit

ViewPager mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2); 
Waheed Sabir
  • 159
  • 2
  • 4
0

you can show and hide fragments for saving the states, or use the navigation component latest version

Mahdi Zareei
  • 1,299
  • 11
  • 18