简体   繁体   中英

How to avoid Fragment recreation?

I have 2 Fragments F1 and F2 . I open the first Fragment F1 from the Activity using the following code:

MyFragment f1 = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("GameLevelType", "Learn");
dialog.setArguments(bundle);
FragmentTransaction gameTransaction = getSupportFragmentManager().beginTransaction();
gameTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
gameTransaction.add(android.R.id.content, f1).addToBackStack(null).commit();

Then from Fragment F1 I am opening another Fragment F2 using below code:

MySecondFragment f2 = new MySecondFragment();
            Bundle bundle = new Bundle();
            FragmentTransaction transaction = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
            bundle.putInt("CurrentPosition", getAdapterPosition());
            bundle.putIntArray("x", kolamTracingGameList.get(getAdapterPosition()).getX());
            bundle.putIntArray("y", kolamTracingGameList.get(getAdapterPosition()).getY());
            bundle.putInt("Level", (getAdapterPosition() + 1));
            bundle.putString("GameType", "Kolam");
            fragment.setArguments(bundle);
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            transaction.replace(android.R.id.content, f2).addToBackStack(null).commit();

Problem is when I close Fragment F2 and Fragment F1 comes to foreground. Whole F1 is recreating( onViewCreated() is called again). I don't want F1 to get recreated again when it comes to foreground.

For the second fragment use add instead of replace.

replace - removes the existing fragment and adds a new fragment.when the back button is pressed in fragment F2,fragment in oncreateView is called again.

add -retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused'.when the back button is pressed in fragment F2,none of the methods of the fragment F1 are called again.

transaction.add(android.R.id.content, f2).addToBackStack(null).commit();

If you want the Fragment to keep it's state and don't go through onCreateView you can not replace it. Let's take a look at Fragment's life cycle:

When you call replace on a fragment you are basically telling the container to remove all present fragments, and add a new one. If you remove a fragment, onPause() will be called all the way until onViewDestroyed() , that meaning that if you get the fragment instance back and add it to the container, it has no View, so onCreateView() will be called.

If you call add on Fragment2, it will be the Visible Fragment but Fragment1 will still be in the container. Now once you remove Fragment2(backPress or programmatically), Fragment1 will become visible without calling onCreateView() , or any other state.

Code:

Replace this:

transaction.replace(android.R.id.content, f2).addToBackStack(null).commit();

With:

transaction.add(android.R.id.content, f2).addToBackStack(null).commit();

Every time before doing the FragmentTransaction you are creating a new Fragment , either F1 or F2 . You have couple of options:

  1. Keep a global reference to F1/F2 as they are created. So you only create a new one if they are null .
  2. Or, if you don't want to keep global reference, assign a unique tag to the F1/F2 . That way you can call FragmentManager.findFragmentByTag() which will return you the Fragment if it still exists. Then you do your transaction.

Example for option 2:

FragmentManager supportFragmentManager = getSupportFragmentManager();
MyFragment f1 = supportFragmentManager.findFragmentByTag("f1_fragment");

if (f1 != null) f1 = new MyFragment();

FragmentTransaction gameTransaction = supportFragmentManager.beginTransaction();
       gameTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
gameTransaction.replace(android.R.id.content, f1, "f1_fragment")
    .commit();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM