126

Suppose I wish to replace the current fragment in some container view with another. Is it better to use replace...

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, null);
    ft.commit();

... or the following, with show and hide?

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.hide(oldFragment);
    ft.show(newFragment);
    ft.commit();

Is one way of doing this more efficient? Can't find much information on when to use these methods, or how they affect the lifecycle of the fragments involved. Thanks!

Tatarize
  • 10,238
  • 4
  • 58
  • 64
Robert Karl
  • 7,598
  • 6
  • 38
  • 61
  • if i go to fragment B from fragment A and then goes back to fragment A how can i make sure that life cycle event such as onCreateView is not call on fragment A? does find fragment by tag work? – blackHawk May 12 '18 at 14:36

4 Answers4

148

You should consider what you plan to do with the fragment to decide which path to follow. If you use a FragmentTransaction to hide the fragment, then it can still be in the running state of its lifecycle, but its UI has been detached from the window so it's no longer visible. So you could technically still interact with the fragment and reattach its UI later you need to. If you replace the fragment, the you are actually pulling it out of the container and it will go through all of the teardown events in the lifecycle (onPause, onStop, etc) and if for some reason you need that fragment again you would have to insert it back into the container and let it run through all of its initialization again.

If there is a high probability that you will need that fragment again, then just hide it because it's a less expensive operation to redraw it's layout than to completely reinitialize it.

David C. Sainte-Claire
  • 2,461
  • 1
  • 15
  • 12
  • 6
    For our needs, initializing the fragment is pretty expensive, so we'll probably go with `hide()` and `show()` to save on that! Thanks for this! – Robert Karl Nov 01 '12 at 22:05
  • 2
    Hi, when you say detach from window, do you mean onDetach() callback will be called ? I experimented that, it seems it is not the case. – GingerJim Jun 13 '13 at 16:41
  • probably he meant "detach"; a fragment can also be detached / reattached (additionally to add/remove, show/hide) – comeGetSome Dec 27 '13 at 14:45
  • For some reason if i hide on fragment and add another after screen rotation (i do not want to use setRetainInstance(true)), the fragment i previously hid is now shown again under my top fragment, hence having both UIs overlap. Any idea how to counter this ? – AgentKnopf Jun 24 '14 at 09:42
  • 1
    @Zainodis, I have the same problem too. My solution is to save the hidden state of the fragment in onSaveInstanceState() - savedInstanceState.putBoolean(STATE_HIDDEN, isHidden()); then in onCreate() if (savedInstanceState != null) get the hidden state back and if the fragment is hidden then hide it with the transaction. – worawee.s Mar 27 '15 at 05:04
  • 1
    @worawee.s Hey there and thanks for the update :) ! I solved the issue a while ago on my end - I did not really need hide/show etc. so I completely dropped it and now I am going with standards like add/replace or single fragment activities in single pane (master detail flow basically). For those still using hide your solution will be really helpful - and not checking savedInstance != null was one of the mistakes I made before. – AgentKnopf Mar 27 '15 at 09:09
  • What if I use replace() combined with addToStack(), is it the same to show() and hide() methods ? – Allen Vork Apr 01 '18 at 07:51
  • @AllenVork i think it will still replace. you can use `Log.i` inside OnDestroy method and check the output. – M.kazem Akhgary Oct 30 '18 at 06:12
5

You basically answered yourself. If you want to replace (so old fragment is no longer needed) use replace() if you want to temporary hide it then do hide().

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
1

If the view is "heavy" I think the hide/show should be used. There is such callback: onHiddenChanged. If you use hide/show it would be helpful.

Vahan
  • 11
  • 1
0

I used hide/Show method in my activity with 4 fragments its solved my solution but some time randomly when i show my dialog it give window bad token exception when i used add and replace method then bad token exception is not occur so i think show/hide method is not perfect

Dishant Kawatra
  • 638
  • 7
  • 5