运行时配置更改后,DialogFragment变为null

时间:2012-08-10 18:57:18

标签: android android-dialogfragment android-fragmentactivity

我正在学习使用FragmentDialogFragment。作为一项培训,我正在尝试扩展the DialogFragment page中给出的AlertDialog示例。显然一切都很好:当我显示选项菜单并单击其按钮时,会出现一个对话框,其行为与预期一致。但是,如果在显示对话框时配置发生更改(例如,当我旋转屏幕时),则会正确地重新创建对话框,但单击其任何按钮会导致应用程序崩溃。我已经尝试了很多东西(例如,静态newInstancesetRetainInstanceonSaveInstanceState方法和其他记录的建议)来解决问题,但似乎没有任何工作,所以我在初始点。我正在使用支持库v4。

这是我的主要活动代码:

public class MainActivity extends FragmentActivity {
    private MyDialogFragment dlgf;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        showMyDialog();
        return true;
    }

    private void showMyDialog(){
        dlgf = MyDialogFragment.newInstance();
        dlgf.show(getSupportFragmentManager(), "dialog");
    }

    public void doPositive() {
        // do stuff...
        dlgf.getDialog().dismiss();
    }

    public void doNegative() {
        // Cancel button pressed
        dlgf.getDialog().dismiss();
    }
}

这是我的DialogFragment代码:

public class MyDialogFragment extends DialogFragment {
    private View view;

    public static MyDialogFragment newInstance() {
        MyDialogFragment dlgf = new MyDialogFragment();
        return dlgf;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        view = getActivity().getLayoutInflater().inflate(R.layout.alertdialog, null);

        return new AlertDialog.Builder(getActivity())
        .setView(view)
        .setTitle("A Title")
        .setPositiveButton("OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int buttonID) {
                    ((MainActivity)getActivity()).doPositive();
                }
            })
        .setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int buttonID) {
                    ((MainActivity)getActivity()).doNegative();
                }
            })
        .create();
    }

}

单击“取消”按钮后执行崩溃时,logcat会在doNegative方法中显示NullPointerException。如果在单击“确定”按钮后发生崩溃,则会在doPositive方法中出现NullPointerException。很明显DialogFragment对象为空。

有人可以帮帮我吗? TIA

1 个答案:

答案 0 :(得分:2)

最初在Activity中设置dlgf的{​​{1}}实例在配置更改时被销毁,并且创建了一个新实例。那个新的没有设置showMyDialog()所以你得到了NPE。

dlgf内的

getActivity()将返回Fragment附加到的当前活动实例。在您的情况下,它将在新实例中正确调用该方法。

要解决您的问题,您只需将导致回调的Fragment传递给Fragment,这样您就不必存储对它的引用。

Activity

另一种可能性是让// in activity public void doPositive(MyDialogFragment source) { // do stuff... source.getDialog().dismiss(); } // in dialog fragment .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int buttonID) { ((MainActivity)getActivity()).doPositive(MyDialogFragment.this); } }) 使用Activity / MyDialogFragment保留对onRetainNonConfigurationInstance()的引用。