防止在Android中的屏幕旋转对话框解散
我正在尝试防止在“活动”重新启动时使用“警报”构build器构build的对话框被解散。
如果我重载onConfigurationChanged方法,我可以成功地做到这一点,并重置布局,以正确的方向,但我失去了edittext的粘性文本function。 所以在解决对话框问题时,我创build了这个edittext问题。
如果我从edittext中保存string,并在onCofiguration中进行重新分配,它们似乎默认为初始值,而不是旋转前input的值。 即使我强制无效,似乎更新它们。
我真的需要解决对话问题或edittext问题。
谢谢您的帮助。
现在避免这个问题的最好方法是使用DialogFragment
。
创build一个扩展DialogFragment
的新类。 重写onCreateDialog
并返回你的旧Dialog
或AlertDialog
。
然后你可以用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>
只是使用
ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize
和应用程序将知道如何处理旋转和屏幕大小。
您可以将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()); }