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