DialogFragment 忽略 OnBackPressedDispatcher

Posted

技术标签:

【中文标题】DialogFragment 忽略 OnBackPressedDispatcher【英文标题】:DialogFragment ignores OnBackPressedDispatcher 【发布时间】:2019-12-01 06:09:51 【问题描述】:

我正在尝试使用'androidx.activity:activity-ktx:1.1.0-alpha01''androidx.fragment:fragment-ktx:1.2.0-alpha01' 处理BottomSheetDialogFragment(即DialogFragment)中的后退按钮。

handleOnBackPressed() 未被调用,DialogFragment 被解除。 OnBackPressedCallback 在按下返回按钮时启用。

我认为DialogFragment 正在拦截后退按钮的按下,因为ComponentActivity 从不调用mOnBackPressedDispatcher.onBackPressed();

有没有办法覆盖 DialogFragment 处理后退按钮按下?

【问题讨论】:

【参考方案1】:

真的很难理解 Google Android Dev 在做什么。无论如何,我找到了一个不使用接口的解决方案。

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

只需覆盖 onCreateDialog 并在其中覆盖 onBackPressed。

【讨论】:

【参考方案2】:

我找到了解决方案,但我希望库会处理这个用例。

创建自定义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)

【讨论】:

【参考方案3】:

我对 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
        
    

【讨论】:

以上是关于DialogFragment 忽略 OnBackPressedDispatcher的主要内容,如果未能解决你的问题,请参考以下文章

Activity与DialogFragment交互的方法

Dialogfragment 未清除

Android:DialogFragment.dismissInternal 处 DialogFragment.dismissAllow 处的 NullPointerException

DialogFragment.getDialog 返回 null

为啥要使用 DialogFragment?

从 DialogFragment 回调片段