Status Update
Comments
il...@google.com <il...@google.com> #2
Dialogs are separate windows that always sit above your activity's window. This means that the dialog will continue to intercept the system back button no matter what state the underlying FragmentManager is in, or what code you run in your Activity's onBackPressed()
- which is where the OnBackPressedDispatcher
plugs into.
gs...@gmail.com <gs...@gmail.com> #3
If there isn't a workaround then it should be mentioned in the docs or there should be a lint warning.
mi...@fortech.ro <mi...@fortech.ro> #4
il...@google.com <il...@google.com> #5
Re 1.5.0-alpha01
Dialog
, ComponentDialog
was added that has its own OnBackPressedDispatcher
that is tied into the Dialog's onBackPressed()
.
As part of 1.5.0-alpha01
AppCompatDialog
now extends ComponentDialog
, thus allowing any subclass of AppCompatDialog
to also have access to an appropriate OnBackPressedDispatcher
.
As BottomSheetDialogFragment
uses BottomSheetDialog
BottomSheetDialog
extends AppCompatDialog
, upgrading to AppCompat 1.5.0-alpha01 or higher, then your BottomSheetDialogFragment
can indeed access a valid OnBackPressedDispatcher
by getting it from the dialog
:
This allows you to cast the result of super.onCreateDialog()
to a BottomSheetDialog
as part of your overload to onCreateDialog
:
override fun onCreateDialog(savedInstanceState: Bundle?) = super.onCreateDialog(savedInstanceState).also { dialog ->
(dialog as BottomSheetDialog).onBackPressedDispatcher.addCallback(this) {
// Handle back
}
}
Or access the dialog via requireDialog()
from your overload of onViewCreated()
:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) : Dialog {
(requireDialog() as BottomSheetDialog).onBackPressedDispatcher.addCallback(this) {
// Handle back
}
}
on...@gmail.com <on...@gmail.com> #6
Here is an extension to resolve the correct onBackPressedDispatcher
for any fragment:
fun Fragment.resolveOnBackPressedDispatcher(): OnBackPressedDispatcher {
val dialogFragment = findDialogFragment(this)
return if (dialogFragment != null) {
// DialogFragments are running in a separate window
// so they have their own back pressed dispatcher
// https://issuetracker.google.com/issues/149173280
(dialogFragment.requireDialog() as ComponentDialog)
.onBackPressedDispatcher
} else {
requireActivity()
.onBackPressedDispatcher
}
}
private tailrec fun findDialogFragment(fragment: Fragment): DialogFragment? {
return if (fragment is DialogFragment) {
fragment
} else {
val parentFragment = fragment.parentFragment
if (parentFragment != null) {
findDialogFragment(parentFragment)
} else {
null
}
}
}
Description
Version used: 2.2.1
Devices/Android versions reproduced on: Samsung A20/Android 9.0
If this is a bug in the library, we would appreciate if you could attach:
- Sample project to trigger the issue: sample project has been attached
Description
Adding an OnBackPressedCallback in a DialogFragment does not do anything, the dialog just gets popped off normally without the callback being called. See the attached sample for details.