Closed omkar-tenkale closed 2 years ago
A
's view is destroyed, because DefaultFragmentStateChanger
uses attach/detach
by default. From library perspective, this makes most sense, as Google explicitly refused to make it so that the lifecycle of a fragment becomes inactive when it is hidden + it is impossible to make an AndroidX Fragment be both stopped and have a view at the same time.
So if I had used show/hide by default instead of attach/detach, people would be complaining about how their LiveData observers don't get cancelled when they navigate forward and their fragment is off-screen. This would also be because of Google's code, and there would be no way around it other than destroying the view (or creating a 3rd fragment view lifecycle that takes hidden into account, but it's not a very common thing to do).
Some variables initialised in A keep their value but fragment is designed in a way which expects default values for fields in onCreateView
Well you are supposed to extract the state either into the Fragment or into a scoped model like so and save-restore it across process death like so because of how Android works.
However, it is possible to retain the view of fragments quite easily actually, because simple-stack is configurable like that (unlike Jetpack Navigation where you'd basically need to rewrite their entire Fragment integration lol)
So keeping views is as simple as this (but it will make your Fragment not be stopped when you go to another screen, it calls onHiddenChanged
instead)
public class KeepViewFragmentStateChanger extends DefaultFragmentStateChanger {
public KeepViewFragmentStateChanger(FragmentManager fragmentManager, int containerId) {
super(fragmentManager, containerId);
}
@Override
protected void startShowing(@Nonnull FragmentTransaction fragmentTransaction, @Nonnull Fragment fragment) {
fragmentTransaction.show(fragment);
}
@Override
protected void stopShowing(@Nonnull FragmentTransaction fragmentTransaction, @Nonnull Fragment fragment) {
fragmentTransaction.hide(fragment);
}
@Override
protected boolean isNotShowing(@Nonnull Fragment fragment) {
return fragment.isHidden();
}
}
If you need to completely kill A when you go to B (and not be able to navigate back to it on back), then use replaceTop
, setHistory
or exitScopeTo
If you need to completely kill A when you go to B (and not be able to navigate back to it on back),
I want to completely kill A AND be able to navigate back!
@omkar-tenkale then use setHistory
with a different fragment tag (see that uuid option in the other issue 😜 ) when you are navigating to A
isn't there a better solution? 😅
Well, you're trying to destroy the previous fragment, so you need to have a different key for it - or at least a key that provides a different fragment tag.
So setHistory
sounds like the way to go 🤔
Closing for now ..
I have 2 fragments A and B
AKey() -> A() -> BKey() -> B() -> goBack()
Expected behaviour: AKey's createFragment should be called again and new fragment object instance to be created
Actual behaviour: Old A instance's onCreateView is called again
Problem: Some variables initialised in A keep their value but fragment is designed in a way which expects default values for fields in onCreateView
Is this an issue with how i'm initialising fragments or should i work with manual statechanger or what.. i'm confused