1

My issue is quite simple. I'm using fragments over an activity with a tablayout (but not a viewpager). All my fragments inherit from a BaseFragment class, which has this function:

public void pushFragmentAnimated(BaseFragment fragment) {
    mActivity.pushFragmentAnimated(fragment);
}

In the activity, pushFragmentAnimated() is:

public void pushFragmentAnimated(BaseFragment fragment) {
    try {
        mCurrentFragment = fragment;
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
        transaction.replace(R.id.fragment_container, fragment, fragment.TAG);
        transaction.addToBackStack(fragment.getFragmentTitle());
        transaction.commit();

        manager.executePendingTransactions();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Problem is, using this function, i never get my fragment state saved, and whenever i pop my current fragment, the fragment below reloads as a new one.

In fact, in my BaseFragment i have two functions, which i usually override in every fragment:

public void initializeFragment() {}

public void setupFragmentData() {}

Those functions are called here:

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = getView();

    if (view == null && savedInstanceState == null) {

        int layoutResource = getFragmentLayout();
        view = inflater.inflate(layoutResource, container, false);

        // ButterKnife bind
        ButterKnife.bind(this, view);

        // Initialization methods
        initializeFragment();
    }

    return view;
}

and here:

@Override
public void onResume() {
    super.onResume();

    // Initialization methods
    setupFragmentData();
}

and the first one, initializeFragment(), always gets called when i pop a fragment, even though it shouldn't. Only the second should, as you can see.

Any idea?

Will998
  • 35
  • 5
  • Have a look at [this answer](https://stackoverflow.com/a/9245510/2357147). You might not be instantiating your Fragment correctly, and Android has some gotchas with regards to Fragment instantiation. – Isosymmetric Sep 12 '18 at 14:45
  • Is the "top" fragment saving/restoring its state correctly? That is, is the problem only happening for fragments in the back stack, or is it happening for every single one? – Ben P. Sep 12 '18 at 14:54
  • @BenP. every single one – Will998 Sep 12 '18 at 15:16
  • And have you implemented `onSaveInstanceState()` etc? – Ben P. Sep 12 '18 at 15:16
  • My guess is that your Activity is generating new Fragments on every rotation, as opposed to using the Fragments that already exist inside the FragmentManager – Ben P. Sep 12 '18 at 15:17
  • @BenP. yes sir! – Will998 Sep 12 '18 at 15:18
  • @BenP. i guess so... just wondering why – Will998 Sep 12 '18 at 15:19
  • Well, how do you add the Fragments the very first time your activity is launched? Are you absolutely certain that that code doesn't run every time the device is rotated? – Ben P. Sep 12 '18 at 15:20
  • @BenP. i push the fragment on a FrameLayout above my TabLayout, using a code very similar to the above pushFragmentAnimated(), but without the animation. – Will998 Sep 12 '18 at 15:27
  • @BenP. sorry, what do you mean with device rotated? I'm not rotating my device :P – Will998 Sep 12 '18 at 15:28

2 Answers2

0

I recommend you to use this snippet code in your fragment:

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // here you can save your variables value
}

and save your arbitrary fields in outState bundle.

also as @Isosymmetric said, you can have a look at this answer.

Milad Yarmohammadi
  • 1,253
  • 2
  • 22
  • 37
0

That's because you make replace. If possible - use add and it should save state of underlying fragments. If it is not possible - use solution @MilaDroid suggests.

BTW, is there any specific reason to using replace and adding it to back stack?

Mike
  • 2,547
  • 3
  • 16
  • 30
  • If i use add, it saves the state, but when i go back to the previous fragment, my setupFragmentData() doesn't get called. I guess it's because it's just a fragment added on top of another. Uhm... – Will998 Sep 12 '18 at 15:15
  • So data can be changed in Fragment while they are in the back stack? – Mike Sep 12 '18 at 15:20
  • Yep, with "add" i can even see the previous fragment under the current fragment – Will998 Sep 12 '18 at 15:26
  • What do you mean? – Will998 Sep 12 '18 at 15:31
  • In case you have fixed amount of fragments you can declare space for it in layout. If fragments are dynamic I believe there is no Android-way to restore state. As soon as you replace previous fragment, its state is lost. You can store state of it somewhere in Activity and then pass it to fragment, but I think it complicates things.. – Mike Sep 12 '18 at 18:51
  • I marked your answer as correct, since i used a combination of **add** and **hide**/**show** to obtain what i wanted. Thanks! – Will998 Sep 13 '18 at 10:57