Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:警报对话框和片段_Android_Android Activity_Callback_Android Alertdialog_Android Fragments - Fatal编程技术网

Android:警报对话框和片段

Android:警报对话框和片段,android,android-activity,callback,android-alertdialog,android-fragments,Android,Android Activity,Callback,Android Alertdialog,Android Fragments,我正在将我的一个应用程序切换到片段(从仅仅是活动)中,要么我完全遗漏了一些东西,要么它们使显示AlertDialog的整个过程变得非常复杂 首先,我要做的是:显示几个警报对话框中的一个,其中有一个正按钮和一个负按钮,每个底部都有相关的回调方法。对话框需要在屏幕旋转后继续存在(即:重新创建) 以前:在过去,你所要做的就是用正确的回调方法创建一个AlertDialog,然后显示它,系统会处理包括屏幕旋转在内的所有事情 现在:如果我从我的片段创建并显示AlertDialog,它不会在屏幕旋转期间重新创

我正在将我的一个应用程序切换到片段(从仅仅是活动)中,要么我完全遗漏了一些东西,要么它们使显示AlertDialog的整个过程变得非常复杂

首先,我要做的是:显示几个警报对话框中的一个,其中有一个正按钮和一个负按钮,每个底部都有相关的回调方法。对话框需要在屏幕旋转后继续存在(即:重新创建)

以前:在过去,你所要做的就是用正确的回调方法创建一个AlertDialog,然后显示它,系统会处理包括屏幕旋转在内的所有事情

现在:如果我从我的片段创建并显示AlertDialog,它不会在屏幕旋转期间重新创建,并且根据LogCat在销毁期间泄漏内存。根据新开发人员关于片段的文档,我应该使用DialogFragment来创建AlertDialog,以便片段管理器可以处理屏幕旋转等事情(请参见此处:在Alert Dialog标题下)。这很好,但是,问题在于回调方法。在提供的示例中,它们硬编码为活动中的两个方法。我有两个问题,我不想让活动参与这个过程,我需要为我创建的不同AlertDialog使用不同的回调方法。我真的不想为我将要创建的每个AlertDialog创建具有硬编码回调的不同类。必须有一个更简单的方法,否则这就是愚蠢:)

另一种表达方式。。。片段管理器在屏幕旋转后使用创建过程中保存的任何“参数”重新创建片段。这些参数保存在捆绑包中,但是,我无法在捆绑包中保存回调方法,因此片段管理器无法使用传递的回调方法重新创建片段,只能使用硬编码的回调方法,这意味着对于我将要显示的每种类型的AlertDialog,我需要使用硬编码回调方法的单独类。。。这是愚蠢的还是我错过了什么

谢谢你的帮助, Harry

调用setRetainInstance(true)将导致FragmentManager保存您的实际片段实例。它不会破坏和重新创建片段,而是将相同的片段传递给新的活动

使用setRetainInstance(true)时需要注意的主要一点是,一个片段实例可能会在片段的生命周期内看到对onCreateView()和onDestroyView()的多次调用,因为它与不同的活动相关联。因此,如果您在onCreateView()中注册了一个BroadcastReceiver,并在onDestroy()中注销了它,那么您的代码在setRetainInstance(false)中可以正常工作,而在setRetainInstance(true)中则不能正常工作

编辑-不仅是这个答案是错误的,但我


所以我应该得到所有的反对票。:)setRetainInstance(true)上有一个bug,您可以通过一个粗略的hack调用getDialog()来修复。setDismissMessage(null)在您的DialogFragment的onDestroyView()中进行破解。

您可以使用接口稍微整理硬编码回调

在下面的示例中,我的对话框片段类指定了一个名为
Host
的接口。想要使用此片段的活动必须实现
MyAlertDialog.Host
接口,并具有它定义的两种方法。当然,您可以使用
onReport
onRetry
,而不是通用的
onOptionOne
onoption两个
名称,这对每个警报都是有意义的

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;

public class MyAlertDialog extends DialogFragment {

    /**
     * Host activities have to implement this interface to receive button click
     * callbacks.
     * 
     */
    public static interface Host {
        public void onOptionOne();

        public void onOptionTwo();
    }

    public static MyAlertDialog newInstance() {
        return new MyAlertDialog();
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                Host host;
                try {
                    host = (Host) getActivity();
                } catch (ClassCastException e) {
                    String name = getActivity().getClass().getName();
                    throw new RuntimeException("Class " +  name + " doesn't implement MyAlertDialog.Host interface");
                }

                if (which == DialogInterface.BUTTON_POSITIVE)
                    host.onOptionOne();
                if (which == DialogInterface.BUTTON_NEGATIVE)
                    host.onOptionTwo();
            }
        };

        return new AlertDialog.Builder(getActivity())
                .setMessage("Message here")
                .setPositiveButton("Option One", clickListener)
                .setNegativeButton("Option Two", clickListener)
                .create();
    }
}

这样做的好处是,
MyAlertDialog
不引用任何特定的活动。当活动选择使用此对话框时,它必须实现其契约。相反,对话将与活动结合起来,并与活动挂钩。

感谢您的建议,但它似乎无法解决问题。当使用您建议的方法时,屏幕旋转后,该对话框不会再次出现。不太清楚为什么,因为从逻辑上讲它是有意义的,但不幸的是它没有意义。我知道在我的例子中,以下代码将完成这项工作:
DialogFragment dialog=/*create dialog fragment*/;FragmentTransaction ft=getFragmentManager().beginTransaction();显示(ft,列表_对话框)这是从我的一些代码中提取出来的-在您的情况下,您必须创建AlertDialog等等。