Background: I wrote a custom container which is capable of holding three fragments. Depending on the state of this container only two or those three fragments are visible. To inform fragments that their visibility was changed I tried out two options:
I called Fragment.setUserVisibleHint() method with respective value. Hosted fragments overrode this method and react appropriately. This worked out.
I called FragmentTransaction.hide() and FragmentTransaction.show() methods to hide and show fragments. Hosted fragments overrode Fragment.onHiddenChanged() and reacted as needed. This worked out as well.
My problem is that I am not satisfied with either of these options. I would like to put invisible fragment into a standard paused state. Advantage of this option is that I keep the code clean and simple, as I don't need to override any special methods (like setUserVisibleHint()
or onHiddenChanged()
) and I can handle everything inside onPause()
and onResume()
which are already implemented.
Question: What is the proper way to put a fragment into a paused state and then to resume it from that state?
Update: I tried out FragmentTransaction.detach()
too. This is not an option because it destroys the view, which is not allowed in my case.
Detaching the Fragment with detach() will put the Fragment through the onPause , onStop and finally onDestroyView life-cycle methods, and then when you re-attach it with attach() it will go through onCreateView , onStart and finally onResume life-cycle methods.
During an activity, press and hold left to stop the clock and pause your activity. To restart the activity again, press right.
when your activity is recreated, the fragment gets destroyed. So you have to create new instance of fragment and add it again. Ok, but you cant retain the fragment view. If you want to retain the data which is in fragment, then use onSaveInstanceState() and onRestoreInstanceState() .
The onResume() get called always before the fragment is displayed. Even when the fragment is created for the first time . So you can simply move your from onViewCreated() to onResume . Save this answer.
Sounds like you want to call FragmentTransaction#attach and FragmentTransaction#detach to put your fragment through the life-cycle routines the same as FragmentPagerAdapter (see source here).
Detaching the Fragment
with detach()
will put the Fragment
through the onPause
, onStop
and finally onDestroyView
life-cycle methods, and then when you re-attach it with attach()
it will go through onCreateView
, onStart
and finally onResume
life-cycle methods.
You must make sure you are using tag's as-well as container-id since you can have multiple fragments attached to a single container and you will have to be able to get the Fragment
reference from the FragmentManager
which will then have to be done via its tag.
FragmentTransaction.setMaxLifecycle() method can be used for this purpose. To pause a fragment just set its maximum state to STARTED
:
// hide and pause the fragment
transaction.hide(fragment)
transaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED)
// show and resume the fragment
transaction.setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
transaction.show(fragment)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With