常见的Dialog,常用的isShowing方法,用此方法常判断dialog是否正在显示,但是有时发现dialog没有显示,此方法也是返回true,这就尴尬了。
取消显示dialog的方法
一、点击返回按钮或者点击dialog之外的屏幕
/**
* Called when the dialog has detected the user's press of the back
* key. The default implementation simply cancels the dialog (only if
* it is cancelable), but you can override this to do whatever you want.
*/
public void onBackPressed() {
if (mCancelable) {
cancel();
}
}
点击返回按钮,最后调用了cancel的方法;
/**
* Called when a touch screen event was not handled by any of the views
* under it. This is most useful to process touch events that happen outside
* of your window bounds, where there is no view to receive it.
*
* @param event The touch screen event being processed.
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation will cancel the dialog when a touch
* happens outside of the window bounds.
*/
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
cancel();
return true;
}
return false;
}
点击屏幕之外最后也是调用cancel方法
二、看看cancel()方法
/**
* 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();
}
看到源码,cancel方法最后还是调用了dismiss方法
三、看看dimiss()方法
/**
* Dismiss this dialog, removing it from the screen. This method can be
* invoked safely from any thread. Note that you should not override this
* method to do cleanup when the dialog is dismissed, instead implement
* that in {@link #onStop}.
*/
@Override
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
看到源码,dismiss()会调用dismissDialog()方法
四、看看dismissDialog()方法
void dismissDialog() {
if (mDecor == null || !mShowing) {
return;
}
if (mWindow.isDestroyed()) {
Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
return;
}
try {
mWindowManager.removeViewImmediate(mDecor);
} finally {
if (mActionMode != null) {
mActionMode.finish();
}
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
sendDismissMessage();
}
}
看到源码,最后将mShowing = false;
五、再看看hide()方法
/**
* Hide the dialog, but do not dismiss it.
*/
public void hide() {
if (mDecor != null) {
mDecor.setVisibility(View.GONE);
}
}
可以看到并没有将mShowing赋值。所以调用hide方法,隐藏dialog但是isShowing方法还是会返回true。
总结:
1.点击返回按键或者点击dialog之外的屏幕->cancel()->dismiss()->dismissDialog->mShowing = false;
此时dialog没有显示, isShowing方法返回false;
2.调用hide()->dialog隐藏,mShowing依然是true;
此时dialog没有显示,isShowing方法返回true;
本文解析了Android中对话框(Dialog)的显示与隐藏机制,详细介绍了通过点击返回按钮或屏幕外部取消对话框的过程,并对比了cancel、dismiss及hide方法的区别。
279

被折叠的 条评论
为什么被折叠?



