OnBackPressedCallback() 使用 OnBackPressedDispatcher() 不起作用

问题描述

我通过点击 Activity 中实现的 dialog fragment 打开了 recycler view item

对于 back function,我使用了 onBackpressedCallback()

但是,我尝试显示 toast message 进行测试,但没有任何反应。

我将此参考了 Android 开发者文档。

有什么问题?

WC.java (DialogFragment)

public class WritingCommentDialogFragment extends DialogFragment implements CommentModel.EditInputListener {
    OnBackpressedCallback callback;
    
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_writing_comment_dialog,container,false);
        bindViews(view);
        addCommentItem();
        Toast.makeText(getContext(),"onCreateView()",Toast.LENGTH_SHORT).show();
        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);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback.remove();
    }

    @Override
    public void onResume() {
        super.onResume();
        setDialogSize();
    }
}

解决方法

根据this issue

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

如果您将此代码放在 Activity 的 onBackPressed() 中,您会看到同样的问题 - Activity 不再是接收关键事件的窗口(系统后退按钮就是其中之一),因此预计任何插入的东西都不会被触发。

当对话框打开时,唯一接收到系统后退按钮调用的地方是对话框的 onBackPressed() method,这意味着创建您自己的 Dialog 子类(而不是依赖于 {{1 }}) 并手动覆盖该方法。

当然,如果您只想在对话框关闭时回调(即,对话框打开时系统后退按钮的默认行为),那么您需要覆盖 super.onCreateDialog()' s onCancel() method