Dialog的Window的创建过程

Dialog的Window的创建过程和Activity的类似
1、创建Window
与Activity的一样同样是通过PolicyManager的makeNewWindow方法来完成,实际上就是PhoneWindow。

public class Dialog implements DialogInterface, Window.Callback,KeyEvent.Callback, OnCreateContextMenuListener {

Dialog(Context context, int theme, boolean createContextWrapper) {
        if (theme == 0) {
            TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
                    outValue, true);
            theme = outValue.resourceId;
        }

        mContext = createContextWrapper ? new ContextThemeWrapper(context, theme) : context;
        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        Window w = PolicyManager.makeNewWindow(mContext);
        mWindow = w;
        w.setCallback(this);
        w.setWindowManager(mWindowManager, null, null);
        w.setGravity(Gravity.CENTER);
        mListenersHandler = new ListenersHandler(this);
    }
}

2.初始化DecorView并将Dialog的视图添加到DecorView中

public void setContentView(int layoutResID) {
        mWindow.setContentView(layoutResID);
}

3.将DecorView添加到Window中显示
Dialog的show方法,通过WindowManager将DecorView添加到Window中

mDecor = mWindow.getDecorView();
try {
    mWindowManager.addView(mDecor, l);
    mShowing = true;
    sendShowMessage();
    } finally {
}

以上可以看出 Dialog的Window的创建过程和Activity的Window的创建过程很类似。
当Dialog被关闭时,会通过WindowManager来移除DecorView

public void dismiss() {
        if (Looper.myLooper() == mHandler.getLooper()) {
            dismissDialog();
        } else {
            mHandler.post(mDismissAction);
        }
    }

    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.removeView(mDecor);
        } finally {
            if (mActionMode != null) {
                mActionMode.finish();
            }
            mDecor = null;
            mWindow.closeAllPanels();
            onStop();
            mShowing = false;

            sendDismissMessage();
        }
    }

普通的Dialog有一个特殊之处,那就是必须采用Activity的Context,如果采用Application的Context,就会报错。报没有应用token的错误,而应用token一般只有Activity才有,所以只需要用Activity作为Context来显示对话框即可。系统Window比较特殊,它不需要token,如果想要指定对话框为系统Window类型,可以设置WindowManager.LayoutParams.type参数。

dialog.getWindow().setType(LayoutParams.TYPE_SYSTEM_ERROR)

同时不要忘记在AndroidManifest中添加权限。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值