Android Dialog 为什么设置大小需要在 setContentView 方法之后

Dialog设置大小为什么需要在setContentView方法之后?

Dialog设置大小实际也是通过 WindowManager.LayoutParams 中的width,height属性控制

但是我们看到Dialog内部关联的Window(PhoneWindow)的WindowManager.LayoutParams的width,heigh默认值都是MATCH_PARENT,可当我们setContentView之后就变成了WRAP_CONTENT了呢?带着疑问我们我们追踪源码

首先看到Dialog默认关联的Window

Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        //...省略
        final Window w = new PhoneWindow(mContext);
        //...省略
    }

PhoneWindow 继承Window

Window的WindowManager.LayoutParams默认构造(width,height都是 MATCH_PARENT)

接着在看为什么setContentView之后会变了呢

    @Override
    public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        //首次执行这里为空所以条件满足
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
        mContentParentExplicitlySet = true;
    }

继续跟进 installDecor 方法

其中 generateDecor() 方法创建 mDecor 里面方法跟我们的大小没有关系 ,我们重点看 generateLayout 方法

这里我们已经看到大小被修改为了WRAP_CONTENT,但是有个限制就是mIsFloating是否为true

接着我们在验证mIsFloating的值是如何来的

在上图我们看到mIsFloating是解析WindowStyle来的,好的那我们跟进去看

解析 R.styleable.Window 属性

查看我们自己的dialogStyle样式发现windowIsFloating默认值true

所以可以得出当使用Dialog并且样式中有 <item name="android:windowIsFloating">true</item> 时,在setContentView方法之后会重置我们的width,height属性

分析源码得出我们要修改Dialog尺寸时需要在setContentView方法之后

posted @ 2021-06-18 09:08  果冻二筒  阅读(373)  评论(0)    收藏  举报