前言
项目中一个Dialog,要用到hide()、cancel()、show(),在hide()、cancel()执行之后,再次执行show()没有显示弹窗。
方法 | 功能 |
---|---|
hide() | dialog 隐藏,只是执行 mDecor.setVisibility(View.GONE),mShowing 还是 true |
dismiss() | dialog 隐藏,且mDecor = null,mShowing = false,回调OnDismissListener |
cancel() | 调用了dismiss(),且回调OnCancelListener |
show() | dialog 显示 |
原因
调用hide(),再调用dismiss()/cancel()。
此时:View.GONE、mDecor=null、mShowing = false、mCreated=true。
再调用show()。
此时:沿用之前的配置,还是View.GONE,所以dialog没有显示,但是show()是正确地执行完了。
遇到这种问题的解决方法:
1、执行两次show()。
2、使得mCreated = false,例如每次都是dialog 重新创建再去show。
3、慎用hide(),换种方式实现业务逻辑。
/**
* 显示弹窗
*/
public void show() {
//1、如果只是hide,此时mShowing为true,且mDecor!=null,会进入里面执行View.VISIBLE。
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
//2、不是第一次执行show方法,会进入这,沿用之前的配置,如果之前mDecor 为Gone,此时还是Gone。
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
onStart();
mDecor = mWindow.getDecorView();
..省略其他代码..
mShowing = true;
sendShowMessage();
}
/**
* Hide the dialog, but do not dismiss it.
*/
public void hide() {
if (mDecor != null) {
mDecor.setVisibility(View.GONE);
}
}
/**
* Cancel the dialog. This is essentially the same as calling {@link #dismiss()}, but it will
* also call your {@link DialogInterface.OnCancelListener} (if registered).
*/
@Override
public void cancel() {
if (!mCanceled && mCancelMessage != null) {
mCanceled = true;
// Obtain a new message so this dialog can be re-used
Message.obtain(mCancelMessage).sendToTarget();
}
dismiss();
}