Android Fragments 对话片段忽略OnBackPressedDispatcher

v9tzhpje  于 2022-12-29  发布在  Android
关注(0)|答案(4)|浏览(172)

我正在尝试处理BottomSheetDialogFragment中的后退按钮,这是一个DialogFragment,使用'androidx.activity:activity-ktx:1.1.0-alpha01''androidx.fragment:fragment-ktx:1.2.0-alpha01'
不调用handleOnBackPressed(),并且DialogFragment被解除。按下后退按钮时启用OnBackPressedCallback
我认为DialogFragment拦截了后退按钮的按下,因为ComponentActivity从不调用mOnBackPressedDispatcher.onBackPressed();
是否有办法覆盖DialogFragment对后退按钮按下的处理?

dly7yett

dly7yett1#

这真的很难理解谷歌Android开发使.无论如何,我发现了一个解决方案,不使用接口.

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return object : Dialog(requireContext(), theme) {
        override fun onBackPressed() {
            // handle back press
        }
    }
}

只需重写onCreateDialog并重写其中的onBackPressed即可。

jucafojl

jucafojl2#

我找到了一个解决方案,但我希望图书馆会照顾这个usecase。
创建自定义BottomSheetDialog

class BackPressBottomSheetDialog(context: Context, @StyleRes theme: Int, 
private val callback: BackPressBottomSheetDialogCallback) :
        BottomSheetDialog(context, theme) {

    override fun onBackPressed() {
        if (callback.shouldInterceptBackPress()) callback.onBackPressIntercepted()
        else super.onBackPressed()
    }
}

它的interface

interface BackPressBottomSheetDialogCallback {
    fun shouldInterceptBackPress(): Boolean
    fun onBackPressIntercepted()
}

然后在BottomSheetDialogFragment

private val dialogCallback = object : BackPressBottomSheetDialogCallback {
      override fun shouldInterceptBackPress(): Boolean {
        //TODO should you intercept the back button?
      }

      override fun onBackPressIntercepted() {
        //TODO what happens when you intercept the back button press
      }
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return BackPressBottomSheetDialog(requireContext(), theme, dialogCallback)
}
mjqavswn

mjqavswn3#

我对Kotlin的解决方案是:
覆盖BottomSheetDialogFragment中的以下方法。

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return super.onCreateDialog(savedInstanceState).apply {
        setOnKeyListener { _: DialogInterface, keyCode: Int, keyEvent: KeyEvent ->
            if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) {
                // your code
                // return true if you want keep dialog visible
                // return false if you want to dismiss dialog anyway
                return@setOnKeyListener true
            }
            return@setOnKeyListener false
        }
    }
}
uujelgoq

uujelgoq4#

还有一个解决方案:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return super.onCreateDialog(savedInstanceState).also {
        val componentDialog = it as ComponentDialog
        componentDialog.onBackPressedDispatcher.addCallback(this) {
            val backPressedConsumed = yourLegacyLogic()
            if (backPressedConsumed.not()) {
                isEnabled = false
                requireActivity().onBackPressedDispatcher.onBackPressed()
                isEnabled = true
            }
        }
    }
}

解释

向后按下事件传递到DialogFragmentdialog,因此您应该为dialog注册OnBackpressedCallback
禁用回调(isEnabled = false)允许您防止使用下一个back-pressed事件。一旦禁用回调,您将重新触发back-pressed事件(调用requireActivity().onBackPressed()),它将被其他人使用,例如,您的导航将弹出返回堆栈。
之后,您应该启用回调(isEnabled = true)以接收下一个按下鼠标的事件。

相关问题