Closed topnax closed 4 years ago
In quick thoughts: calling setHistory()
should detach all fragments. Calling goTo
and replace
should behave as I have written.
Hey,
This was actually thoroughly discussed in https://github.com/Zhuinden/simple-stack/issues/133#issuecomment-495859930 .
The current behavior is such that fragment B is now detached from the container activity and its view is recreated and not reused, thus consuming unnecessary CPU time.
I fully agree, however using show/hide
does not trigger onStop/onStart
(thus could create unpredictable behavior when using LiveData), while using setMaxLifecycle(CREATED)
destroys the view just like attach/detach
.
As such, I cannot make it the default behavior, even though I theoretically agree with you.
Nonetheless, it is possible to customize the behavior to use show/hide
instead of attach/detach
through the following means:
fragmentStateChanger = object: DefaultFragmentStateChanger(supportFragmentManager, R.id.root) {
override fun isNotShowing(fragment: Fragment): Boolean {
return fragment.isHidden;
}
override fun startShowing(fragmentTransaction: FragmentTransaction, fragment: Fragment) {
fragmentTransaction.show(fragment);
}
override fun stopShowing(fragmentTransaction: FragmentTransaction, fragment: Fragment) {
fragmentTransaction.hide(fragment);
}
}
But the original limitation is not actually on my side, it's on the Fragment side. If you were using replace().addToBackStack()
(as Jetpack Navigation does), they also destroy the view as you navigate forward then back - and Fragments were designed to suit their requirements.
With that, the currently available only alternative that retains the views (show/hide) is demonstrated, and this question is technically resolved.
Just beware that it doesn't alter the Fragment's lifecycle (and trigger onStop). And Fragments are currently unable to trigger onStop without also destroying their views. It's an unfortunate limitation of Fragments.
Let's have a following fragment transactions:
A
=>B
=>C (currently active)
. Now imagine going back in the history, say we callNavigator.backPress(context)
one time. TheB
fragment is at the top of the stack and should be recycled, it'sonCreateView
method should not be called. The current behavior is such that fragmentB
is now detached from the container activity and it's view is recreated and not reused, thus consuming unnecessary CPU time.Would it be possible to recycle fragments in the history that were previously shown?
Could you provide any hints on how to change the
DefaultFragmentStateChanger
or implement it yourself? I think that it is one of the key features that every fragment state changer should implement in my opinion.