0

If I have Fragment A and Fragment B. I call Fragment B from A using below code

FragmentManager fragmentManager =getFragmentManager();
    FragmentTransaction fragmentTransaction =
            fragmentManager.beginTransaction();


    fragmentTransaction.add(R.id.frame_step, fragment,TAG).hide(SourceFragment.this).addToBackStack((SourceFragment.class.getName()));
    fragmentTransaction.commit();

Now in Fragment B I have EditText & I have entered "Hello" in it, if I press back button from Fragment B then according to getSupportFragmentManager().popBackStack(); it will resume Fragment A

Now if I again call Fragment B from Fragment A I want that FragmentB will not get created again and still I can see "Hello" inside EditText.

Note -- I do not want to use variables or shared pref for this as i have multiple fragments with multiple views like a big form. Is there anything that can just call fragment from its resume state instead of calling it again or if i can check if this fragment has already created . Thanks in advance

S.Ambika
  • 292
  • 1
  • 14

2 Answers2

1

What you want is possible. You need to save fragment state before forward navigation and restore it after fragment is restored from backstack.

In Fragment

private Bundle savedState = null;

 @Override
    public void onDestroyView() {
        super.onDestroyView();
        savedState = saveState();
    }

    private Bundle saveState() { /* called either from onDestroyView() or onSaveInstanceState() */
        Bundle state = new Bundle();
        state.putCharSequence("TEXT_HELLO_WORD", helloWordTextView.getText());
        return state;
    }

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        /* (...) */

        if(savedInstanceState != null && savedState == null) {
            savedState = savedInstanceState.getBundle("FRAGMENT_HELLO_WORD");
        }
        if(savedState != null) {
         helloWordTextView.setText(savedState.getCharSequence("TEXT_HELLO_WORD"));
        }
        savedState = null;

        /* (...) */
        return view;
    }
...
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    //Save the fragment's state here somehow like this
    outState.putBundle("FRAGMENT_HELLO_WORD", (savedState != null) ? savedState : saveState());
}

in Activity

public void onCreate(Bundle savedInstanceState) {
    ...
    if (savedInstanceState != null) {
        //Restore the fragment's instance
        mContent = getSupportFragmentManager().getFragment(savedInstanceState, "myFragmentName");
        ...
    }
    ...
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    //Save the fragment's instance
    getSupportFragmentManager().putFragment(outState, "myFragmentName", mContent);
}

Answer compiled from here and here

Hope it helps.

Pavlo Ostasha
  • 14,527
  • 11
  • 35
  • Thanks for your response.I guess This is valid if I have 2-3 views, But What if i have multiple fragments and multiple views in it like a form having multiple steps to be filled. Is there any way to maintain state or just to call fragment from its resume state other than storing data in variables? – S.Ambika Nov 14 '19 at 11:07
  • Like if i can check whether fragment B is already created once and then i can just show that fragment instead of replacing it. – S.Ambika Nov 14 '19 at 11:08
  • Well you can do that, but I would not recommend it since it is not how Android Fragment subsystem works - you will have to override back behaviour, orientation changes and many more that is already done for you in android. Regarding first comment - you may store in a Bundle arbitrary amount of fields and even binary data, but try to keep it less than 1mb - with this limit exceeded you may encounter problems. – Pavlo Ostasha Nov 15 '19 at 09:00
0

The best way to accomplish this in 2019 is by using a Shared ViewModel backing your fragments. You can access data from ViewModel any of the fragments at any time if they are shared between those fragments. The only thing that we need to remember is to initialize ViewModel in the activity context. ref https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

Abhay Paul
  • 31
  • 4