1.构造函数
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
mContext = context;
//获取WindowManager为后续操作做准备
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//创建Window,
final Window w = new PhoneWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
//收到点击或滑动会触发cancel,导致dialog消失
w.setOnWindowSwipeDismissedCallback(() -> {
if (mCancelable) {
cancel();
}
});
//与WindowManager建立联系
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
2.监听状态
这个ListenersHandler用于触发监听
private static final class ListenersHandler extends Handler {
private final WeakReference<DialogInterface> mDialog;
public ListenersHandler(Dialog dialog) {
mDialog = new WeakReference<>(dialog);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DISMISS:
((OnDismissListener) msg.obj).onDismiss(mDialog.get());
break;
case CANCEL:
((OnCancelListener) msg.obj).onCancel(mDialog.get());
break;
case SHOW:
((OnShowListener) msg.obj).onShow(mDialog.get());
break;
}
}
}
比如我们设置setOnDismissListener,就是在创建Dialog消失消息
public void setOnDismissListener(@Nullable OnDismissListener listener) {
if (listener != null) {
mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
} else {
mDismissMessage = null;
}
}
如果我们调用dismiss,首先判断当前线程是不是 当时Dialog创建的线程,是就直接执行,否则通过handler切换线程执行
@Override
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
最终都会执行dismissDialog
@UnsupportedAppUsage
void dismissDialog() {
//如果没有显示,或者DecorView还未创建,就不用消失
if (mDecor == null || !mShowing) {
return;
}
//或者Window已经销毁
if (mWindow.isDestroyed()) {
Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
return;
}
//将DecorView和Window进行销毁
try {
mWindowManager.removeViewImmediate(mDecor);
} finally {
if (mActionMode != null) {
mActionMode.finish();
}
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
sendDismissMessage();
}
}
然后发送 消失消息
private void sendDismissMessage() {
if (mDismissMessage != null) {
// Obtain a new message so this dialog can be re-used
Message.obtain(mDismissMessage).sendToTarget();
}
}
最终执行OnDismissListener接口
((OnDismissListener) msg.obj).onDismiss(mDialog.get());
3.显示
首先给Window添加View
public void setContentView(@NonNull View view) {
mWindow.setContentView(view);
}
然后展示
public void show() {
//如果显示了就不继续操作
if (mShowing) {
if (mDecor != null) {
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
//判断是否处于界面恢复状态
if (!mCreated) {
//如果没有执行onCreate(savedInstanceState)
dispatchOnCreate(null);
} else {
//如果配置发生改变,传递给DecorView
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
onStart();
mDecor = mWindow.getDecorView();
//将Window的DecorView交给WindowManager去显示
mWindowManager.addView(mDecor, l);
if (restoreSoftInputMode) {
l.softInputMode &=
~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
}
mShowing = true;
sendShowMessage();
}