屏幕旋转时Android DialogFragment崩溃

屏幕旋转时Android DialogFragment崩溃,android,exception,android-fragments,nullpointerexception,dialog,Android,Exception,Android Fragments,Nullpointerexception,Dialog,我有一个DialogFragment类。每次我的应用程序中显示多个案例时,我都必须设置侦听器 但当我旋转屏幕时,mListener变为null,当我单击按钮时,会出现NullPointerException。我无法在活动中实现侦听器,因为此对话框有几个案例,每个案例都有不同的操作 CustomDialog类: MyDialogListener mListener; public void show(FragmentManager fm, MyDialogListener listener) {

我有一个DialogFragment类。每次我的应用程序中显示多个案例时,我都必须设置侦听器

但当我旋转屏幕时,mListener变为null,当我单击按钮时,会出现NullPointerException。我无法在活动中实现侦听器,因为此对话框有几个案例,每个案例都有不同的操作

CustomDialog类:

MyDialogListener mListener;

public void show(FragmentManager fm, MyDialogListener listener) {
    mListener = listener;
    super.show(fm, "MyDialog");
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setPositiveButton(android.R.string.ok, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int whichButton) {
                    mListener.onDialogPositiveClick();
                    // NullPointerException after a screen rotate
                }
            })
            .setNegativeButton(android.R.string.cancel, null)
            .create();
}
活动类:

public void showMyFirstDialog() {
    new CutsomDialog().show(getFragmentManager(), mFirstListener);
}

public void showMySecondDialog() {
    new CutsomDialog().show(getFragmentManager(), mSecondListener);
}

侦听器不应作为参数传入,而应作为接口的一部分在dialogfragment本身内实现,并且可能是一个活动。这样,当正/负单击发生时,您可以更新某些内容的数据并将其传递给侦听器。当监听器由活动实现时,它会将数据传递给活动,然后您可以在活动中执行相应的操作

检查以下几个示例-


希望有帮助。

侦听器不应作为参数传入,而应作为接口的一部分在dialogfragment本身中实现,并且可能是一个活动。这样,当正/负单击发生时,您可以更新某些内容的数据并将其传递给侦听器。当监听器由活动实现时,它会将数据传递给活动,然后您可以在活动中执行相应的操作

检查以下几个示例-


希望有帮助。

您不能保留包含DialogFragment的片段的实例字段。使本地数据在配置更改后仍然有效的机制是将片段的参数设置为包含数据的Bundle;此捆绑包将经受住配置更改

第一,消除表演方式;这不是正确的方法。相反,您可以这样做:

DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("TITLE", "Dialog Title Goes Here");
args.putString("MESSAGE", "This is a dialog messaage");
frag.setArguments(args);

frag.show();
public interface DialogListenerProvider {
    DialogListener getDialogListener();
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof DialogListenerProvider) {
        mListener = ((DialogListenerProvider) activity).getDialogListener();
    } else {
        // throw an error
    }
}
然后,您可以在创建AlertDialog时检索标题和消息:

处理DialogListener有点复杂。您不希望在配置更改中保留对该活动的引用,因为它将导致返回到已销毁的活动。相反,您可以安排从片段的onAttach方法内的活动检索侦听器:

您可能需要稍微更改活动类以使其正常工作。如果您使用的是来自许多活动的这个对话框片段,那么在这里定义一个活动可以实现以请求侦听器的接口尤其有用。然后它会像这样:

DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("TITLE", "Dialog Title Goes Here");
args.putString("MESSAGE", "This is a dialog messaage");
frag.setArguments(args);

frag.show();
public interface DialogListenerProvider {
    DialogListener getDialogListener();
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof DialogListenerProvider) {
        mListener = ((DialogListenerProvider) activity).getDialogListener();
    } else {
        // throw an error
    }
}

不能保留包含DialogFragment的片段的实例字段。使本地数据在配置更改后仍然有效的机制是将片段的参数设置为包含数据的Bundle;此捆绑包将经受住配置更改

第一,消除表演方式;这不是正确的方法。相反,您可以这样做:

DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("TITLE", "Dialog Title Goes Here");
args.putString("MESSAGE", "This is a dialog messaage");
frag.setArguments(args);

frag.show();
public interface DialogListenerProvider {
    DialogListener getDialogListener();
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof DialogListenerProvider) {
        mListener = ((DialogListenerProvider) activity).getDialogListener();
    } else {
        // throw an error
    }
}
然后,您可以在创建AlertDialog时检索标题和消息:

处理DialogListener有点复杂。您不希望在配置更改中保留对该活动的引用,因为它将导致返回到已销毁的活动。相反,您可以安排从片段的onAttach方法内的活动检索侦听器:

您可能需要稍微更改活动类以使其正常工作。如果您使用的是来自许多活动的这个对话框片段,那么在这里定义一个活动可以实现以请求侦听器的接口尤其有用。然后它会像这样:

DialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("TITLE", "Dialog Title Goes Here");
args.putString("MESSAGE", "This is a dialog messaage");
frag.setArguments(args);

frag.show();
public interface DialogListenerProvider {
    DialogListener getDialogListener();
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof DialogListenerProvider) {
        mListener = ((DialogListenerProvider) activity).getDialogListener();
    } else {
        // throw an error
    }
}


请发布logcat stacktracewait一分钟后,除夕不到1小时:你为什么需要logcat?mTitle,mMessage和mListener为空发布logcat stacktracewait一分钟后,除夕不到1小时:你为什么需要logcat?mTitle,mMessage,我在同一个活动中有两个对话框,所以我不能在活动中实现它。你能发布更多的代码吗,这样你的调用机制就可以更好地理解。现在还不清楚您试图实现什么。在屏幕旋转后,mListener为null,因此如果我单击对话框中的某个按钮,它将抛出NullPointerException。请告诉我代码的哪一部分对你有帮助。请发布你的活动代码和对话片段代码。我相信,您的mListener正在初始化,但由于旋转,它被重置为null,并且片段没有重新连接到现有活动。使用setRetainInstance true可以在整个活动循环中保留片段,因此即使在活动重新启动时,片段也只是分离并重新连接。这不是问题所在。mFirstListener和mSecondListener是我的活动的局部变量。它们是在declarion初始化的。我在同一个活动中有两个用于此对话框的案例,因此我不能仅在活动中实现它。请发布更多代码,以便更好地理解您的调用机制。有点不清楚你想要达到的目标是什么
屏幕旋转后,s of now.mListener为null,因此如果单击对话框中的按钮,它将抛出NullPointerException。请告诉我代码的哪一部分对你有帮助。请发布你的活动代码和对话片段代码。我相信,您的mListener正在初始化,但由于旋转,它被重置为null,并且片段没有重新连接到现有活动。使用setRetainInstance true可以在整个活动循环中保留片段,因此即使在活动重新启动时,片段也只是分离并重新连接。这不是问题所在。mFirstListener和mSecondListener是我的活动的局部变量。它们在declarion时初始化。我在同一个活动中有两个用于此对话框的案例,因此我不能仅在活动中实现它。@User-这使它变得容易;只需将activity参数强制转换为onAttach中的DialogListener,将引用隐藏在instance字段中,并根据需要使用它。我在同一个activity中有两个用于此对话框的案例,因此我不能仅在activity中实现它。@User-这样做很简单;只需将activity参数强制转换为onAttach中的DialogListener,将引用隐藏在instance字段中,并根据需要使用它。