防止在Android中的屏幕旋转对话框解散

我正在尝试防止在“活动”重新启动时使用“警报”构build器构build的对话框被解散。

如果我重载onConfigurationChanged方法,我可以成功地做到这一点,并重置布局,以正确的方向,但我失去了edittext的粘性文本function。 所以在解决对话框问题时,我创build了这个edittext问题。

如果我从edittext中保存string,并在onCofiguration中进行重新分配,它们似乎默认为初始值,而不是旋转前input的值。 即使我强制无效,似乎更新它们。

我真的需要解决对话问题或edittext问题。

谢谢您的帮助。

Solutions Collecting From Web of "防止在Android中的屏幕旋转对话框解散"

现在避免这个问题的最好方法是使用DialogFragment

创build一个扩展DialogFragment的新类。 重写onCreateDialog并返回你的旧DialogAlertDialog

然后你可以用DialogFragment.show(fragmentManager, tag)来显示它。

下面是一个Listener的例子:

 public class MyDialogFragment extends DialogFragment { public interface YesNoListener { void onYes(); void onNo(); } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (!(activity instanceof YesNoListener)) { throw new ClassCastException(activity.toString() + " must implement YesNoListener"); } } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setTitle(R.string.dialog_my_title) .setMessage(R.string.dialog_my_message) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ((YesNoListener) getActivity()).onYes(); } }) .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ((YesNoListener) getActivity()).onNo(); } }) .create(); } } 

在你打电话的活动中:

 new MyDialogFragment().show(getSupportFragmentManager(), "tag"); // or getFragmentManager() in API 11+ 

这个答案有助于解释这三个问题(和他们的答案):

  • Android最好的方法避免对话框在设备旋转后closures
  • Android的DialogFragment与对话框
  • 如何使用兼容性包显示DialogFragment?
 // Prevent dialog dismiss when orientation changes private static void doKeepDialog(Dialog dialog){ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.copyFrom(dialog.getWindow().getAttributes()); lp.width = WindowManager.LayoutParams.WRAP_CONTENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; dialog.getWindow().setAttributes(lp); } 
 public static void doLogout(final Context context){ final AlertDialog dialog = new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.titlelogout) .setMessage(R.string.logoutconfirm) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ... } }) .setNegativeButton("No", null) .show(); doKeepDialog(dialog); } 

如果你改变方向变化的布局,我不会把你的清单中的android:configChanges="orientation" ,因为你正在重新创build视图。

使用这些方法保存活动的当前状态(如input的文本,显示的对话框,显示的数据等):

 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } 

这种方式活动通过onCreate再次,然后调用onRestoreInstanceState方法,您可以再次设置您的EditText值。

如果你想存储更复杂的对象,你可以使用

 @Override public Object onRetainNonConfigurationInstance() { } 

在这里,你可以存储任何对象,并在onCreate你只需要调用getLastNonConfigurationInstance(); 获取对象。

这个问题很久以前就回答了。

然而,这是我自己使用的 简单简单的解决scheme。

我为自己做了这个辅助类 ,所以你也可以在你的应用程序中使用它。

用法是:

 PersistentDialogFragment.newInstance( getBaseContext(), RC_REQUEST_CODE, R.string.message_text, R.string.positive_btn_text, R.string.negative_btn_text) .show(getSupportFragmentManager(), PersistentDialogFragment.TAG); 

要么

  PersistentDialogFragment.newInstance( getBaseContext(), RC_EXPLAIN_LOCATION, "Dialog title", "Dialog Message", "Positive Button", "Negative Button", false) .show(getSupportFragmentManager(), PersistentDialogFragment.TAG); public class ExampleActivity extends Activity implements PersistentDialogListener{ @Override void onDialogPositiveClicked(int requestCode) { switch(requestCode) { case RC_REQUEST_CODE: break; } } @Override void onDialogNegativeClicked(int requestCode) { switch(requestCode) { case RC_REQUEST_CODE: break; } } } 

一个非常简单的方法是从方法onCreateDialog()创build对话框(参见下面的注释)。 你通过showDialog()显示他们。 这样,Android为你处理旋转,你不必在onPause()调用dismiss() onPause()来避免WindowLeak,然后你不必恢复对话框。 从文档:

显示由此活动pipe理的对话框。 第一次为一个给定的id调用onCreateDialog(int,Bundle)时,将使用相同的id进行调用。 之后,对话框将自动保存并恢复。

有关更多信息,请参阅Android文档showDialog() 。 希望它可以帮助别人!

注意:如果使用AlertDialog.Builder,不要从onCreateDialog()调用show() onCreateDialog() ,而是调用create() 。 如果使用ProgressDialog,只需创build对象,设置你需要的参数并返回它。 总之,在onCreateDialog() show()内的show()会导致问题,只需创buildde对话框实例并返回它。 这应该工作! (我遇到了使用onCreate()中的showDialog() – 实际上不显示对话框的问题,但是如果您在onResume()或侦听器callback中使用它,则效果不错)。

只需在AndroidManifest.xml中的activity元素中添加android:configChanges =“orientation”即可

例:

 <activity android:name=".YourActivity" android:configChanges="orientation" android:label="@string/app_name"></activity> 

您可以将Dialog的onSave / onRestore方法与Activity的onSave / onRestore方法结合使用,以保持对话框的状态。

注意:这种方法适用于那些“简单”的对话框,比如显示一条警告消息。 它不会重现embedded到对话框中的WebView的内容。 如果你真的想阻止一个复杂的对话在轮换期间被解雇,请尝试Chung IW的方法。

 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); myDialog.onRestoreInstanceState(savedInstanceState.getBundle("DIALOG")); // Put your codes to retrieve the EditText contents and // assign them to the EditText here. } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Put your codes to save the EditText contents and put them // to the outState Bundle here. outState.putBundle("DIALOG", myDialog.onSaveInstanceState()); } 

只是使用

 ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize 

和应用程序将知道如何处理旋转和屏幕大小。