繁体   English   中英

OnBackPressedCallback 未在底部工作表对话框片段中调用

[英]OnBackPressedCallback not called in Bottom Sheet Dialog Fragment

我有一个Bottom Sheet Dialog Fragment ,其中包含四个带有ViewPagerFragment 我想在Bottom Sheet Dialog Fragment中单击onBackPressed时调用一个方法。 在我的OnCreateView中实现OnBackPressedCallback但它没有被触发。 任何人都知道为什么不调用它?

val callback = object : OnBackPressedCallback(true */ true means that the callback is enabled /*) {
    override fun handleOnBackPressed() {
        // Show your dialog and handle navigation
        LogUtils.d("Bottom Sheet -> Fragment BackPressed Invoked")
    }
}

// note that you could enable/disable the callback here as well by setting callback.isEnabled = true/false
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)

我在寻找 DialogFragment 中存在的相同问题的解决方案时发现了这个线程。 答案在上面的评论中,但为了完整起见,这里是汇总的信息:

解决方案

在您的 DialogFragment 中覆盖 onCreateDialog 并设置 OnKeyListener:

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 onBackPressed logic here -->

                    return@setOnKeyListener true
                }
                return@setOnKeyListener false
            }
        }
    }

解释

针对requireActivity().onBackPressedDispatcher.addCallback对 DialogFragments 不起作用的问题( https://issuetracker.google.com/issues/149173280 ):

对话框是始终位于活动窗口上方的单独窗口。 这意味着无论底层 FragmentManager 处于什么状态,或者您在 Activity 的 onBackPressed() 中运行什么代码(OnBackPressedDispatcher 插入的位置),对话框都将继续拦截系统后退按钮。

本质上,当使用任何使用对话框的组件时, onBackPressedDispatcher是错误的工作工具,因为它们在应用程序中的行为方式以及在活动之外(在顶部)存在的方式。

@ITJscott 解释得很好。 万一任何人在这里难以理解/实现 kotlin 代码是相同的 JAVA 代码片段。

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    Dialog mDialog = super.onCreateDialog(savedInstanceState);
    mDialog.setOnKeyListener((dialog, keyCode, event) -> {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {

            // <-- Your onBackPressed logic here -->
            requireActivity().onBackPressed();
            return true;
        }
        return false;
    });
    return mDialog;
}

如果您已将底部工作表设置为不可取消使用,也会发生此行为。

因此,为避免这种情况,您可以使用以下代码来检测某些事件,例如键盘输入或后按。 如果要对其他事件执行其他操作,可以在此处添加代码。

bottomSheetDialog.setOnKeyListener { _, keyCode, _ ->
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            onBackPressed()
            return@setOnKeyListener true
        } else {
            return@setOnKeyListener false
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM