FragmentTransaction.hide()- findings

Nav Singh
Nav Singh
Jul 17 · 4 min read
Story header

Today, We will learn about the hidden costs of hiding fragments over replacing fragments.

Recently, I found an issue with following code in one of my sample project so, I have decided to share it with you.

Fragment transaction

What happens when we call hide on any fragment transaction :

  • It hides an existing fragment.
onHiddenChanged method

It just hides the views, fragment is still in RESUMED state 🤯🤯🤯🤯

How it can effects the performance of the App :

  • Let say you update Textview’s text by observing livedata from ViewModel,then It will keep sending the changes to the UI because fragment is in RESUMED state.
Update UI based on livedata value

As you can see MainFragment is not visible to the user but instead of replacing it with SecondFragment we call the hide on fragment transaction which just hides it’s view. It’s still in RESUMED state and keep sending the updates to the UI

  • As we discussed because fragment is still in RESUMED state that means it keeps the references for all the resources which leads to memory leaks/wastage issues.
    Ex : ViewBinding’s stay alive and keep the references to all it’s views, resources, etc.

popBackStack :

  • Pop the last fragment transition from the manager’s fragment back stack
popBackStack
  • Check the logs when POP BACK STACK pressed, you can see that it triggers the onHiddenChangedof MainFragment which sets the visibility to TRUE
popBackStack logs

Overlapped content issue :

At some point, If you want to load full screen fragment then you can load it to android.R.id.content instead of adding it to existing container but at this point in existing container(R.id.container) RESUMED fragment is still accessible although it’s overlapped by fragment which is added to android.R.id.content.

Overlapped content accessible

As you can see in the logs content of fragment which is hidden under android.R.id.contentis still accessible.

Tricky solutions to fix this behavior :

  • You might do the trick to add background color to the top mostfragment’s layout’s parent tag so that underlying content will not be visible but any random click on UI can put you in a situation where you don’t expect to be.

Or

  • Set the clickListener on parent tag of fragment’s layout which is loaded into android.R.id.content so that any clicks on screen can’t go beyond it’s content.
parentTag clickListener

Recommend solution to fix this issue :

  • Before loading the fragment into android.R.id.content clear the backStack so that only required content is visible
clear backStack

or

  • hide all the previous fragments because 2 different fragments are in RESUMED state in 2 different containers

So whenever you are handling multiple fragments you need to be careful to make sure that you are not wasting resources and also at particular instance only required content is visible, not something which is not important or relevant to the current flow.

It’s totally up to you whatever works(hide/replace) for you go for it.

Nerd For Tech

From Confusion to Clarification

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Nav Singh

Written by

Nav Singh

Mobile Software Engineer at Manulife. GDG Organizer at GDG Montreal.

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.