-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DialogFragment and BottomSheetDialogFragment as part of navigation stack #250
Comments
Heyo! Historically, The reason why dialogs never made it into it is because that suddenly introduces the concept of "destination parent-child relationships", namely that a DialogFragment does not exist alone: it is in fact automatically recreated by the fragmentManager. So it means there is a separation between how these fragments are managed, and suddenly some fragments are connected to others. You need to consider that "if a DialogFragmentKey is showing, then the KEY UNDER IT is the ACTUAL top key, and the dialog on top is a tracking of an event". Then we must consider that that DialogFragment should track that when it is As such, it was easier to say that if something is a dialog, then the fragment itself starts it. You could definitely say that "but Jetpack Navigation has its own support for DialogFragments, surely it's a solveable problem" yes, and they do the tricks I mentioned above for tracking whether a DialogFragment should still be tracked as a destination, and they do this via LifecycleOwner, and at the time this did not exist nor would it have been actually worth it in comparison to just creating the DialogFragment via |
Thank you for your quick response! Well, I was thinking to treat the DialogFragment and BottomSheetDialogFragment as a usual Fragment by implementing them myself. Usual Fragment just with some animation, size difference and that their will be shown with a visible dimmed background. In this scenario I will not have this kind of issues, right? |
Well technically in that case they aren't really DialogFragment/BottomSheetDialogFragment, right? 😅 Something that has been historically tricky with fragments is to use an animation that opens them from below and be shown on top of the previous fragment, theoretically they created I have previously used the following code in a real project for such customization: class FragmentStateChanger(
fragmentManager: FragmentManager,
@IdRes containerId: Int
) : DefaultFragmentStateChanger(fragmentManager, containerId) {
override fun onForwardNavigation(
fragmentTransaction: FragmentTransaction,
stateChange: StateChange
) {
val topNewKey = stateChange.topNewKey<FragmentKey>()
//val topPreviousKey = stateChange.topPreviousKey<FragmentKey>()
if (topNewKey.shouldAnimateInFromBelow) {
fragmentTransaction.setCustomAnimations(
R.anim.slide_in_to_center,
R.anim.animate_do_nothing,
R.anim.slide_in_to_center,
R.anim.animate_do_nothing
)
} else {
super.onForwardNavigation(fragmentTransaction, stateChange)
}
}
override fun onBackwardNavigation(
fragmentTransaction: FragmentTransaction,
stateChange: StateChange
) {
val topNewKey = stateChange.topNewKey<FragmentKey>()
val topPreviousKey = stateChange.topPreviousKey<FragmentKey>()
if (topPreviousKey?.shouldAnimateInFromBelow == true) {
fragmentTransaction.setCustomAnimations(
R.anim.animate_do_nothing,
R.anim.slide_out_from_center,
R.anim.animate_do_nothing,
R.anim.slide_out_from_center
)
} else {
super.onBackwardNavigation(fragmentTransaction, stateChange)
}
}
override fun onReplaceNavigation(
fragmentTransaction: FragmentTransaction,
stateChange: StateChange
) {
val newKey = stateChange.topNewKey<FragmentKey>()
if (newKey.shouldDisableAnimationOnReplace) {
// do nothing
} else {
super.onReplaceNavigation(fragmentTransaction, stateChange)
}
} Where
With a key like abstract class FragmentKey: DefaultFragmentKey(), DefaultServiceProvider.HasServices {
// ...
open val shouldAnimateInFromBelow: Boolean = false
open val shouldDisableAnimationOnReplace: Boolean = false
// ...
} Along with this hacky thing that allowed for the same hack that FragmentContainerView uses, but with the ability to configure whether it should be applied or not https://gist.github.com/Zhuinden/6ccd443d09c49f43f13b6169ae3d7966 As mentioned in this issue Zhuinden/simple-stack-extensions#5 (comment) I am 100% guaranteed this looks daunting, but thankfully that part is a solved problem. Fragments have a lot of benefits, but their animation support kinda sucks, and has historically always sucked. Which is why these hoops exist at all. 😅 Anyway, as for the dimmed background, the trick is that you would want the previous fragment to show underneath, correct? If this is your plan, you might need to define parent-child relations to make sure that the "child" is This requires a custom FragmentStateChanger implementation, although this is totally okay, the library itself does not enforce you to use And this is why we typically just did (And technically, Putting dialogs in the backstack creates a lot of edge-cases, I was very surprised when Google invented "dialog destinations" back when. That's my take on it anyway |
Technically no, I was just implying that I'm aiming for this kind of behavior, sorry 😬
Well I'm not suprised that this the solution when working with fragments.
Yes, this is the tricky part. Thank you very much for your help! |
You're welcome. Technically I've been thinking about this since, and I've remembered that it seems to be a common requirement to have smaller translucent fragments without it being dialogs. This would require to add the last fragment, but not detach the one above it. Technically I could theoretically add support for this in a non-breaking manner via a custom interface, if it is supported by DefaultFragmentStateChanger. I'll take it into consideration. Till then though, I'd still advise using DialogFragment, it's really nice. 😅 |
I really like this libary and was wondering how to implement navigation for dialog and bottomsheet fragments.
Their are 2 reasons for this:
I was thinking about a own backstack for each fragment, but with a custom StateChanger where instead of attach/detach or show/hide would be used add/remove so that the fragments that are underneath could be visible.
Maybe you could give a hint about how you would do this kind of navigation or maybe why I should not do this, maybe there are some downsides to this.
The text was updated successfully, but these errors were encountered: