您好我正在开发一个使用地图的应用。
我正在使用Fragment Activity和一个名为Fragment-A的片段。
在Fragment-A中有一个按钮,当点击该按钮弹出一个Dialog Fragment时,会显示一个地图,其中包含先前从服务器收到的某个位置。
让我们说这个对话框片段是DialogFragment-B。
它有一个关闭的按钮,一个导航到谷歌地图应用程序以获取路线的按钮。
如果用户导航到DialogFragment-B并返回到Fragment-A,通过单击关闭按钮,每个东西都能正常工作。
但是如果用户点击后退按钮,现有的对话框片段将正常关闭,应用程序正常运行。
但是,如果用户然后按下主页按钮或接到电话呼叫,并且即使DialogFragment-B之前被解除,也会调用onResume,它会重新出现并按下close会使应用程序出现空指针异常
这是我打开DialogFragment-B的代码。
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
android.app.Fragment prev = fm.findFragmentByTag(MY_MAP);
if (prev != null) {
ft.remove(prev);
}
MyMapFragmentDialog newFragment = MyMapFragmentDialog
.newInstance(eachPost);
newFragment.show(ft, MY_MAP);
在DialogFragment-B中单击关闭按钮,我调用MyMapFragmentDialog.this.dismiss();
如果有人遇到过这个问题并且克服了这个问题,请指导我。
答案 0 :(得分:13)
我遇到了同样的问题,确保我在super.onDismiss(dialog)
子类的onDismiss
方法中调用DialogFragment
来解决问题。
答案 1 :(得分:2)
更新:Kalina的答案是一个更优雅,更简单的解决方案 - 正如我后来想到的那样!
我在我的一个应用程序中面临同样的问题,并且没有在任何地方找到答案,请查看DialogFragment类的源代码,该类可在以下位置获得:
然后,我在onDismiss(DialogInterface对话框)方法的源代码中找到了在注释中写的可能原因:
// Note: we need to use allowStateLoss, because the dialog
// dispatches this asynchronously so we can receive the call
// after the activity is paused. Worst case, when the user comes
// back to the activity they see the dialog again.
我从中理解的是解雇是不保存到实例状态,当活动恢复时,它会立即再次显示它作为实例状态恢复的一部分 - 假设片段是永远不会被解雇。作为异步事件,没有安全的方法来提交解雇而不冒险
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
异常和随之而来的崩溃,这可能是班级作者选择这样做的原因。
适用于我的解决方案 是通过以下方式分别监控DialogFragment的状态:
-
@Override
public void onDismiss(DialogInterface dialog) {
// dialogDismissed is a Class level variable in the containing Activity,
// must be set to false each time the DialogFragment is shown
dialogDismissed = true;
}
注意:如果DialogFragment是一个单独的类,则需要从onDismiss调用Activity中的方法来执行此操作,可能是通过设置接口
然后必须在活动onResume()中检查此标志并强制关闭(在检查对话框不为空之后):
-
@Override
public void onResume() {
super.onResume();
//...
if (dialogDismissed && dialog != null) {
dialog.dismiss();
}
}