Problem
I'm using Jetpack Compose Navigation with dialog destinations. When I show a DialogFragment on top of a Compose Navigation Dialog, the order is correct. But after backgrounding the app and returning, the DialogFragment appears under the Compose Dialog instead of on top.
Code
// Compose Navigation Dialog
NavHost(navController) {
dialog<MyDestination> {
MyScreen()
}
}
@Composable
fun MyScreen() {
val fragmentManager = LocalParentFragmentManager.current
Button(onClick = {
// Show third-party DialogFragment
MyDialogFragment().show(fragmentManager, "dialog")
}) {
Text("Show Dialog")
}
}
Steps to Reproduce
- Navigate to Compose Dialog (via NavController)
- Click button to show DialogFragment
- Press HOME button
- Return to app
- Bug: DialogFragment is now under Compose Dialog ❌
Expected vs Actual
Before Background: After Background:
┌─────────────────┐ ┌─────────────────┐
│ DialogFragment │ ←Top │ Compose Dialog │ ←Top
├─────────────────┤ ├─────────────────┤
│ Compose Dialog │ │ DialogFragment │
└─────────────────┘ └─────────────────┘
Question
How do I maintain correct z-order between Compose Navigation Dialogs and DialogFragments across app backgrounding?
Workaround
Dismissing DialogFragments in onStop() fixes it, but users lose dialog state:
override fun onStop() {
super.onStop()
parentFragmentManager.fragments
.filterIsInstance<DialogFragment>()
.forEach { it.dismissAllowingStateLoss() }
}
Is there a better solution?
Environment: Compose 1.5.x, Navigation 2.7.x, API 24-34
Note: DialogFragment is from third-party library (cannot modify)
Tags: android jetpack-compose android-dialogfragment compose-navigation