【问题标题】:What is the difference between onBackPressed and onCancel in DialogFragment?DialogFragment 中的 onBackPressed 和 onCancel 有什么区别?
【发布时间】:2021-06-07 19:43:41
【问题描述】:

当尝试使用dialog fragment 的后退按钮时

我很好奇使用onBackPressed()(或onBackPressedCallBack)和onCancel()之间的区别。

我尝试在dialog fragment中使用onBackPressedCallback()OnBackPressedDispatcher()定义back key的数据转发事件,但是没有成功。

最后,我使用onCancel()传递了数据。

为什么onBackPressed() 的后退键不起作用?

更新

public class WritingCommentDialogFragment extends DialogFragment {
    OnBackPressedCallback callback;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


        return view;
    }
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        callback =  new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                Toast.makeText(getContext(), "TEST", Toast.LENGTH_SHORT).show();
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
    }

}

【问题讨论】:

    标签: java android kotlin android-dialogfragment onbackpressed


    【解决方案1】:

    onBackPressed() 的对话框本身会在主机 Activity 收到消息之前拦截后退按钮的按下。默认行为是在对话框上调用cancel(),而不是将其传递给 Activity。这就是为什么将回调添加到 Activity 没有做任何事情的原因。如果您想专门处理后退按钮按下,您需要继承 Dialog 以覆盖它并将该类用作您在 onCreateDialog() 中创建的 Dialog。像这样的:

    public class MyDialogFragment extends DialogFragment {
    
        @NotNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            Dialog dialog = new Dialog(requireContext(), getTheme()) {
                @Override
                public void onBackPressed() {
                    MyDialogFragment.this.onBackPressed();
                    // And maybe you also want to call cancel() here.
                }
            };
            dialog.setCanceledOnTouchOutside(false);
            return dialog;
        }
    
        private void onBackPressed() {
            // your code here
        }
    }
    

    对话框不仅会在按下返回键时被取消,而且如果用户在对话框外部点击或按下取消按钮(如果您在对话框中添加了一个),或者如果您手动调用 cancel() 或它的宿主 DialogFragment。因此,在onCancel() 中执行您的操作所涵盖的事件不仅仅是按下后退按钮。

    您可以挂钩的第三种可能事件(使用 OnDismissListener)是正在关闭的对话框,即在它关闭的任何时候,包括当它被取消或屏幕旋转时。

    【讨论】:

    • 我的英文不太好,所以你的回答有些地方有点难懂。 1.不是很明白onBackPressed() of the dialog itself intercepts the back button press before the host Activity ever gets a shot at it.的意思,能解释清楚一点吗? 2.not pass it on to the Activity.,你不通过是什么意思? 3.adding your callback to the Activity中的代码是onAttach()中的代码吗?谢谢你,对不起......
    • 1.当按下返回按钮时,操作系统调用dialog.onBackPressed(),而不是activity.onBackPressed()。因此,您无法使用 Activity 更改对话框中后退按钮的行为。您只能通过继承 Dialog 并覆盖 Dialog.onBackPressed() 来做到这一点。
    • 2.如果你查看Dialog.onBackPressed()的源代码,你会看到它调用dialog.cancel()并且不对Activity做任何事情,这就是为什么如果你在对话框打开时按下后退按钮,Activity.onBackPressed()永远不会被调用. “不通过”是指它不会将消息传递给按下后退按钮的 Activity。
    • 3.是的,我指的是您在onAttach() 中创建并使用getOnBackPressedDispatcher().addCallback() 提供给您的活动的 OnBackPressedCallback。当调用 onBackPressed 函数时,您正在告诉 Activity 您希望它做什么,但如果屏幕上显示 Dialog,则不会调用该函数。
    • 没有可覆盖的DialogFragment.onBackPressed()。您可以在DialogFragment.onCreateDialog() 中返回 Dialog 子类的实例。我添加了一个如何做到这一点的例子。是的,关于你的最后一个问题。
    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 2010-10-02
    • 2011-12-12
    • 2010-09-16
    • 2012-03-14
    • 2012-02-06
    • 2011-02-25
    • 2011-11-22
    相关资源
    最近更新 更多