DialogFragment和返回按钮

32

有没有可能在DialogFragment中拦截按键呢?抱歉问题有点幼稚..我的FragmentActivityonBackPressed从未被调用。

提前致谢

    if (imageFile.exists()) {
            ShowPicDialog newFragment = ShowPicDialog.newInstance();
            FragmentTransaction ft = manager.beginTransaction();
            Fragment prev = manager.findFragmentByTag("picDialog");
            if (prev != null) {
                ft.remove(prev);
            }

            ft.addToBackStack("picDialog");
            newFragment.getArguments().putString("path", imageFile.getAbsolutePath());
            newFragment.show(ft, "picDialog");
        }

抱歉,我添加了用于显示对话框的代码片段。


你是在使用兼容库,还是在 Honeycomb 设备/模拟器上测试? - Jason LeBrun
我更新了我的答案并提供了更多信息。简而言之,当您创建对话框时,它会创建一个新的Activity,因此FragmentActivity不再接收按键事件。您需要在DialogFragment中设置对话框,以便它为您处理后退键。 - Jason LeBrun
4个回答

33

很难确定问题所在,因为您没有发布任何代码。但我猜测您还没有通过调用 FragmentTransaction 中的 addToBackStack 方法将 DialogFragment 添加到后退栈中,以便将其添加到活动中。

Android文档页面上有示例,展示了在活动中使用DialogFragment的好模式

由于正在显示对话框,因此创建的对话框将接收按键事件,而不是父活动。因此,在创建对话框片段时设置Dialog.OnKeyListener,并在 Dialog 上调用 setCancelable(false) 以防止返回键关闭它。然后,您可以在 OnKeyListeneronkey 方法中处理返回键。


你是不是想用 setCancelable 而不是 isCancelable - rgamber

14

如何最好地处理使用返回按钮的DialogFragment:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    return new Dialog(getActivity(), getTheme()){
        @Override
        public void onBackPressed() {
            // On backpress, do your stuff here.
        }
    };
}

6

Rahul Pundhir的答案在不使用建造者模式时非常好用。如果您在对话框上使用了Builder模式,则可以改用以下方法:

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        AlertDialog alertDialog = new AlertDialog.Builder(getContext())
                .setTitle(...)
                .setPositiveButton(...)
                .setNegativeButton(...)
                .setMessage(...)
                .create();

        alertDialog.setOnKeyListener((dialog, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_BACK 
                && event.getAction() == KeyEvent.ACTION_UP) {
                // TODO do the "back pressed" work here
                return true;
            }
            return false;
        });

        return alertDialog;
    }

这是通过模拟系统如何调用onBackPressed()(忽略跟踪和监听ACTION_UP)来实现的。请参见Dialog源代码


2
你可以在 Dialog/ComponentDialog 和 BottomSheetDialog 中使用它, 只需将强制转换的对话框更改为您所需的类型的对话框即可。
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
       return super.onCreateDialog(savedInstanceState).also { dialog ->
        //change the ComponentDialog with your type of dialog
        (dialog as ComponentDialog).onBackPressedDispatcher.addCallback(this, object : 
            OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // your code
            }
        })
    }
}

这个解决方案对我很有帮助。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接