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

标签 android android-dialogfragment android-fragmentactivity

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

这是我的主要 Activity 代码:

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 对象为 null。

有人可以帮我吗? TIA

最佳答案

最初在 showMyDialog() 中设置 dlgfActivity 实例在配置更改时被销毁,并创建一个新实例。新的没有设置 dlgf,因此您会得到 NPE。

Fragment 内的

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

要解决您的问题,您只需将导致回调的 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 使用 onRetainNonConfigurationInstance()/getLastNonConfigurationInstance() 保留对其 MyDialogFragment 的引用.

关于android - 运行时配置更改后 DialogFragment 变为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11907641/

相关文章:

android - 访问 char[] 时出现段错误

android - 删除方法后 fragment 仍然可见

android - 如何为网站创建功能齐全的 Android 应用程序?

android - 启动 Intent.ACTION_SEND 总是返回 resultCode 0

java - 公共(public)方法对同一包中的其他类不可见

android - 在DialogFragment中,onCreate应该做什么?

Android更改来自另一个 fragment 的 ListView 项目

android - popBackStackImmediate 从第 4 个 fragment 到第 2 个 fragment ?

Android Gradle Sync 失败找不到 support-core-ui.aar

android - 从 DialogFragment 设置状态栏颜色