【问题标题】:Preventing the back button from cancelling a DialogFragment防止后退按钮取消 DialogFragment
【发布时间】:2012-04-27 15:31:40
【问题描述】:

我有一个可以创建和弹出 DialogFragment 的 Fragment,但是当我点击后退按钮时,即使我明确调用 setCancelable(false); 也会关闭对话框;有什么办法让我的 DialogFragment 对后退按钮不敏感?

public class LoadingDialogFragment extends DialogFragment
{
    String title;
    String msg;

    public LoadingDialogFragment()
    {
        this.title = "Loading...";
        this.msg = "Please wait...";
    }
    public LoadingDialogFragment(String title, String msg)
    {
        this.title = title;
        this.msg = msg;
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState)
    {
        final ProgressDialog dialog = new ProgressDialog(getActivity());

        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setIndeterminate(true);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setCancelable(false);

        return dialog;
    }

}

我从 AsyncTask 创建 DialogFragment:

private class GpsTask extends AsyncTask<String, Integer, Integer>
{
    //ProgressDialog dialog;
    @Override
    protected void onPreExecute()
    {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        DialogFragment newFragment = new LoadingDialogFragment("Gathering Location", "Acquiring GPS lock...");
        ft.addToBackStack(null);
        newFragment.show(ft, "dialog");
    }

    @Override
    protected Integer doInBackground(String... params)
    {
        //acquire a GPS lock and grab a few position updates
    }

    @Override
    protected void onProgressUpdate(Integer... input) { }

    @Override
    protected void onPostExecute(Integer result)
    {
        getSupportFragmentManager().popBackStackImmediate();
    }
}

【问题讨论】:

    标签: android android-asynctask progressdialog fragment back-button


    【解决方案1】:

    使用setCancelable怎么样?你试过了吗?

    来自文档:

    控制显示的对话框是否可取消。用这个代替 直接调用Dialog.setCancelable(boolean),因为DialogFragment 需要基于此改变其行为

    用于自定义 DialogFragment

    onCreateDialog处添加isCancelable = false

    【讨论】:

    • 这是正确的!事实证明,您必须在 DialogFragment 本身上调用 setCancelable(false),而不是在它拥有的内部 Dialog 上调用!
    • @MattF 此评论可救命。没有意识到我需要在DialogFragment 上调用setCancelable() 而不是ProgressDialog。谢谢!
    • 我在 Kotlin 中使用了 isCancelable = false,在 onViewCreated 内部,它成功了!!
    • 它也适用于我@Seven,我使用 isCancelable = false(不是 dialog.setCancelable(false))
    • 我使用的是getDialog.setCancelable(false),但它不起作用,但我将它替换为setCancelable(false),它工作正常。这很奇怪
    【解决方案2】:

    我完全不确定这是否适用于 FragmentDialogs,但如果 setCancelable 对您不起作用,可能值得一看这篇文章:Android: Prompt user to save changes when Back button is pressed

    它解释了如何检测按下的后退按钮。所以也许你可以抑制按钮按下它会阻止对话框关闭?

    【讨论】:

    • 我最终选择了另一个答案,但我确实认为这也有效,非常感谢
    【解决方案3】:

    onCreateDialogonCreateView:

    实现应该覆盖这个类并实现 onCreateView(LayoutInflater, ViewGroup, Bundle) 提供内容 的对话框。或者,他们可以覆盖 onCreateDialog(Bundle) 创建一个完全自定义的对话框,例如 AlertDialog,其 自己的内容。

    使用onCreateDialog时的重要提示:

    重写以构建您自己的自定义对话框容器。这通常是 用于显示 AlertDialog 而不是通用 Dialog;做的时候 所以, onCreateView(LayoutInflater, ViewGroup, Bundle) 不需要 由于 AlertDialog 负责自己的内容,因此可以实施。

    示例Dialog(在本例中为AlertDialog):

    public static class MyAlertDialogFragment extends DialogFragment {
    
        public static MyAlertDialogFragment newInstance(int title) {
            MyAlertDialogFragment frag = new MyAlertDialogFragment();
            Bundle args = new Bundle();
            args.putInt("title", title);
            frag.setArguments(args);
            return frag;
        }
    
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            int title = getArguments().getInt("title");
    
            return new AlertDialog.Builder(getActivity())
                    .setIcon(R.drawable.alert_dialog_icon)
                    .setTitle(title)
                    .setCanceble(false)
                    .setPositiveButton(R.string.alert_dialog_ok,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                ((FragmentAlertDialog)getActivity()).doPositiveClick();
                            }
                        }
                    )
                    .setNegativeButton(R.string.alert_dialog_cancel,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                ((FragmentAlertDialog)getActivity()).doNegativeClick();
                            }
                        }
                    )
                    .create();
        }
    } 
    

    属性setCanceble(boolean) 说明您是否可以通过后按退出Dialog。无需在任何地方捕获 KEYCODE_BACK。

    【讨论】:

    • 这不起作用。您必须在DialogFragment 上拨打setCancelable(boolean),而不是在您现在正在做的Dialog 上。
    【解决方案4】:
     DialogFragment newFragment = YourFragment.newInstance();
                    newFragment.setCancelable(false);
                    newFragment.show(fragmentTransaction, "dialog");
    

    在 .Show() 片段之前添加 setCancelable(false)

    【讨论】:

    【解决方案5】:

    也许对你有帮助。

    newFragment.setCancelable(false); 
    

    在创建 DialogFragment 对象时或在自定义 DialogFragment 的构造函数中进行类似的更改,如下例所示。

    public static CustomClearHourDialog newInstance(Bundle args, IDialogListener listener)
            {
                CustomClearHourDialog clearHourDialog = new CustomClearHourDialog();            
                CustomClearHourDialog.listener = listener;
                clearHourDialog.setCancelable(false);
                return clearHourDialog;
            }
    

    【讨论】:

      猜你喜欢
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 2012-08-22
      • 2010-09-08
      • 2012-04-18
      相关资源
      最近更新 更多