galex
05/23/2023, 9:59 AMBackHandler
doesn't work inside BottomSheetDialogFragment
, how can I intercept it on the dialog and forward it myself to Compose which is the UI within BottomSheetDialog
?galex
05/23/2023, 3:32 PMonBackPressed
event and dismisses the dialog.
To have Compose be connected to it, we have to do the following:
In your fragment, catches the dialog when created:
private lateinit var dialog: ComponentDialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return BottomSheetDialog(requireContext(), theme).apply {
fullyExpanded()
notDraggable()
withoutBackgroundDim()
}.also { dialog = it }
}
Prepare the following extensions on `ComponentDialog`:
private val ComponentDialog.asBackPressedDispatcherOwner: OnBackPressedDispatcherOwner
get() = object : OnBackPressedDispatcherOwner {
override val lifecycle: Lifecycle
get() = this@asBackPressedDispatcherOwner.lifecycle
override val onBackPressedDispatcher: OnBackPressedDispatcher
get() = this@asBackPressedDispatcherOwner.onBackPressedDispatcher
}
And then the only missing piece is in your ComposeView to wrap the content with `CompositionLocalProvider`:
CompositionLocalProvider(
LocalOnBackPressedDispatcherOwner provides dialog.asBackPressedDispatcherOwner
) {
MainChatScreen(::dismiss)
}
Maybe @Ian Lake will tell me I missed something else, but in the meantime this seems to work 🤔Ian Lake
05/23/2023, 4:09 PMOnBackPressedDispatcherOwner
as of Activity 1.5.0: https://developer.android.com/jetpack/androidx/releases/activity#1.5.0Ian Lake
05/23/2023, 4:10 PMIan Lake
05/23/2023, 4:13 PMViewTreeOnBackPressedDispatcherOwner
on the returned dialog so that LocalOnBackPressedDispatcherOwner
picks it upIan Lake
05/23/2023, 4:14 PMIan Lake
05/23/2023, 4:17 PMIan Lake
05/23/2023, 4:18 PMgalex
05/24/2023, 8:29 AMoverride fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return BottomSheetDialog(requireContext(), theme).apply {
(...)
initViewTreeOwners()
}
}
Here's it setting those itsefl:
private fun ComponentDialog.initViewTreeOwners() {
window?.decorView?.let {
it.setViewTreeLifecycleOwner(this)
it.setViewTreeOnBackPressedDispatcherOwner(this)
it.setViewTreeSavedStateRegistryOwner(this)
}
}
Thanks for the whole explanation and update on AppCompat release, I will be able to remove this at some point!