我有一个FragmentActivity支持v4类,它实现了两个并排(类似gmail)片段和一个可以调出DialogFragment的按钮。
除非我有方向改变,否则这一切都很有效。当我有方向更改时,不会保存片段的状态。
主要问题是如果我打开了FragmentDialog,它就会消失。
我已在所有片段中设置setRetainInstance(true);
,但它没有帮助。
在我的清单中,我包括android:configChanges="orientation"
,但仍然没有帮助。
以下是我的代码示例,感谢您的帮助。
public class AddMasterDialog extends DialogFragment {
private int mTitle;
private int mPrompt;
private OnClickListener onSaveListener;
private OnClickListener onCancelListener;
public AddMasterDialog newInstance(int title, int prompt) {
AddMasterDialog simpleDialog = new AddMasterDialog(title, prompt);
return simpleDialog;
}
public AddMasterDialog() {
// Empty constructor required for DialogFragment
}
public AddMasterDialog(int title, int prompt) {
// Empty constructor required for DialogFragment
mTitle = title;
mPrompt = prompt;
}
public void setSaveButton(OnClickListener save){
onSaveListener = save;
}
public void setCancelButton(OnClickListener cancel){
onCancelListener = cancel;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//if(savedInstanceState == null){
View view = inflater.inflate(R.layout.add_new_simple, container);
getDialog().setTitle(mTitle);
((TextView) view.findViewById(R.id.add_simple_new_value_prompt)).setText(mPrompt);
Button saveButton = (Button) view.findViewById(R.id.add_simple_save_button);
saveButton.setOnClickListener(onSaveListener);
//Cancel Button
Button cancelButton = (Button) view.findViewById(R.id.add_simple_cancel_button);
cancelButton.setOnClickListener(onCancelListener);
return view;
//}
}
}
并在我的主要活动中:
private void initiateAddMasterPopupWindow() {
try {
addMasterDialog = new AddMasterDialog(R.string.add_new_master_dialog_title, R.string.add_master_new_value_prompt);
addMasterDialog.setSaveButton(saveNewMasterClickListener);
addMasterDialog.setCancelButton(cancelNewMasterClickListener);
FragmentManager fm = getSupportFragmentManager();
addMasterDialog.show(fm, ADD_NEW_MASTER);
} catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:72)
好的,问题似乎与DialogFragment
兼容性库有关。
this帖子中描述了该问题。
"片段的过时DISMISS消息保留在消息队列中。它在排除旧对话框时被DialogFragment.onDestroyView()
排队,并在创建新对话框后重新激活。
快速(可能很脏)的解决方法是覆盖onDestroyView()
并在调用super.onDestroyView()
之前清除解雇侦听器"
将以下代码添加到DialogFragment解决了这个问题:
@Override
public void onDestroyView() {
if (getDialog() != null && getRetainInstance()) {
getDialog().setDismissMessage(null);
}
super.onDestroyView();
}
答案 1 :(得分:13)
为了不同原因出现同样问题的穷人(我)的利益,我将发布这个。只要执行以下操作,就应自动保留对话框片段:
Activity onSaveInstanceState()
,请确保拨打超级功能!!!! 。就我而言,这是关键。还要确保你在Fragment中做同样的事情。setRetainInstance
,则需要手动存储值并重新应用它们。否则,在大多数情况下,你应该不用担心它。如果你做的事情有点复杂,你可能需要setRetainInstance(true)
,否则忽略它。在我的情况下,我需要使用它为我的一个班级存储一个随机种子,否则我没事。您不需要像手动存储片段那样做任何奇特的事情,如果您按照这些步骤操作,则应该自动完成。总的来说,对于拥有更现代化支持库的任何人来说,这似乎都可以解决问题。
答案 2 :(得分:2)
在我的情况下,我有一个DialogFragment显示另一个使用
的DialogFragmentlistDialogFragment.show(getChildFragmentManager(), "TAG");
将其更改为
listDialogFragment.show(getActivity().getSupportFragmentManager(), "TAG");
解决了问题
答案 3 :(得分:1)
除了设置setRetainInstance(true);
之外,只需将以下代码放入DialogFragment
即可。这是一个经过测试的解决方案。
private boolean isDismissible = false;
@Override
public void dismiss() {
try {
isDismissible = true;
super.dismiss();
Log.d(getClass().getSimpleName(), "Dialog dismissed!");
} catch (IllegalStateException ilse) {
}
}
@Override
public void onDismiss(DialogInterface dialog) {
// So that dialog should not dismiss on orientation change
if (isDismissible) {
// So that dialog can be dismissed
super.onDismiss(dialog);
}
}