屏幕旋转后恢复对话框
Restoring a dialog after screen rotation
在屏幕旋转(纵向到横向或反之亦然)期间,我遇到了一个比尝试恢复 activity 中的错误对话框更重要的小问题。错误发生时对话框确实正确呈现,但在屏幕旋转时对话框未正确恢复。而是整个画面变得昏暗,什么都看不见。这是相关代码:
private void showErrorDialog() {
// assume hasErrorDialog is true at this point
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SomeActivity.this);
LayoutInflater inflater = SomeActivity.this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_alert, null);
dialogBuilder.setView(dialogView);
TextView msgText = (TextView) dialogView.findViewById(R.id.alertMessageText);
msgText.setText("something went wrong");
Button okButton = (Button) dialogView.findViewById(R.id.alertOkButton);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
alertDialog.dismiss();
hasErrorDialog = false;
}
});
alertDialog = dialogBuilder.create();
alertDialog.show();
RelativeLayout rl = (RelativeLayout) findViewById(R.id.someActivity);
int width = rl.getWidth();
alertDialog.getWindow().setLayout((int) (0.9 * width), ViewGroup.LayoutParams.WRAP_CONTENT);
}
当 在 加载 activity 之后调用上述方法时,发生了错误,对话框加载并正常运行。所以上面的代码在正常情况下调用是完全有效的。
但是,我添加了使用保存的实例状态的逻辑来尝试 "remember" 实际上应该有一个错误对话框。旋转时,我尝试在检查此实例状态后再次调用上述方法:
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBoolean("HASERRORDIALOG", hasErrorDialog);
}
然后在 onCreate()
中我尝试检查此状态,如果存在,再次调用 showErrorDialog()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.some_activity);
if (savedInstanceState != null) {
hasErrorDialog = savedInstanceState.getBoolean("HASERRORDIALOG");
if (hasErrorDialog) {
// this does not load the dialog correctly
showErrorDialog();
}
}
}
我在 Stack Overflow 上阅读的大多数 questions/answers 通过建议使用 DialogFragment
来解决这个问题。虽然我愿意朝这个方向发展,但我想知道我当前的代码是否没有补救措施。
运行 @MikeM 的精彩评论,我意识到问题是我的 activity 的 RelativeLayout
尚未在 onCreate()
方法中完全创建,因此它的宽度不是我所期望的(可能为零)。
作为解决方法,我使用 getDisplayMetrics()
访问实际设备宽度,它在生命周期中调用 onCreate
时仍然存在:
alertDialog = dialogBuilder.create();
alertDialog.show();
int width = (int)(getResources().getDisplayMetrics().widthPixels*0.90);
alertDialog.getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);
这里要吸取的教训是,当对话框基于布局中的某些内容时,有一个潜在的警告。在这种情况下,在设备旋转后尝试在 onCreate
中恢复该对话框会失败,但这是一种可能的解决方法。
在屏幕旋转(纵向到横向或反之亦然)期间,我遇到了一个比尝试恢复 activity 中的错误对话框更重要的小问题。错误发生时对话框确实正确呈现,但在屏幕旋转时对话框未正确恢复。而是整个画面变得昏暗,什么都看不见。这是相关代码:
private void showErrorDialog() {
// assume hasErrorDialog is true at this point
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SomeActivity.this);
LayoutInflater inflater = SomeActivity.this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_alert, null);
dialogBuilder.setView(dialogView);
TextView msgText = (TextView) dialogView.findViewById(R.id.alertMessageText);
msgText.setText("something went wrong");
Button okButton = (Button) dialogView.findViewById(R.id.alertOkButton);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
alertDialog.dismiss();
hasErrorDialog = false;
}
});
alertDialog = dialogBuilder.create();
alertDialog.show();
RelativeLayout rl = (RelativeLayout) findViewById(R.id.someActivity);
int width = rl.getWidth();
alertDialog.getWindow().setLayout((int) (0.9 * width), ViewGroup.LayoutParams.WRAP_CONTENT);
}
当 在 加载 activity 之后调用上述方法时,发生了错误,对话框加载并正常运行。所以上面的代码在正常情况下调用是完全有效的。
但是,我添加了使用保存的实例状态的逻辑来尝试 "remember" 实际上应该有一个错误对话框。旋转时,我尝试在检查此实例状态后再次调用上述方法:
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBoolean("HASERRORDIALOG", hasErrorDialog);
}
然后在 onCreate()
中我尝试检查此状态,如果存在,再次调用 showErrorDialog()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.some_activity);
if (savedInstanceState != null) {
hasErrorDialog = savedInstanceState.getBoolean("HASERRORDIALOG");
if (hasErrorDialog) {
// this does not load the dialog correctly
showErrorDialog();
}
}
}
我在 Stack Overflow 上阅读的大多数 questions/answers 通过建议使用 DialogFragment
来解决这个问题。虽然我愿意朝这个方向发展,但我想知道我当前的代码是否没有补救措施。
运行 @MikeM 的精彩评论,我意识到问题是我的 activity 的 RelativeLayout
尚未在 onCreate()
方法中完全创建,因此它的宽度不是我所期望的(可能为零)。
作为解决方法,我使用 getDisplayMetrics()
访问实际设备宽度,它在生命周期中调用 onCreate
时仍然存在:
alertDialog = dialogBuilder.create();
alertDialog.show();
int width = (int)(getResources().getDisplayMetrics().widthPixels*0.90);
alertDialog.getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);
这里要吸取的教训是,当对话框基于布局中的某些内容时,有一个潜在的警告。在这种情况下,在设备旋转后尝试在 onCreate
中恢复该对话框会失败,但这是一种可能的解决方法。