美文网首页
#Android View是如何被添加到窗口上?

#Android View是如何被添加到窗口上?

作者: 刘小厨 | 来源:发表于2020-03-22 15:23 被阅读0次

    我们看下布局加载的入口

    说明:本文讲的Activity为 \color{red}{android.app.Activity} 不同于\color{red}{AppCompatActivity},翻源码的同学注意下~

    Activity->onCreate()-> setContentView(\color{red}{R.layout.activity});

    其中\color{red}{setContentView()}方法调用了 getWindow().setContentView(layoutResID);

     public void setContentView(@LayoutRes int layoutResID) {
            getWindow().setContentView(layoutResID);
            initWindowDecorActionBar();
        }
    

    \color{red}{getWindow()}方法返回的是\color{red}{Window}对象

    \color{red}{Window}是一个抽象类,存在唯一实现\color{red}{PhoneWindow}

    所以我们看下\color{red}{PhoneWindow}\color{red}{setContentView()}方法都做了什么,代码如下:

        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;
        }
    

    这里主要做了两件事

    • \color{red}{installDecor()}方法初始化\color{red}{DecorView}
    • \color{red}{mLayoutInflater.inflate(layoutResID, mContentParent)}解析布局资源文件

    第一步\color{red}{installDecor()} 在这个方法里如果\color{red}{DecorView}==\color{blue}{null}创建一个实例
    \color{red}{DecorView}创建之后,调用\color{red}{generateLayout(m Decor)}根据系统主题性加载配置不同的系统布局资源文件(例:\color{red}{R.layout.screen\_simple}),将布局资源文件inflate后,添加到\color{red}{DecorView}

    注: \color{red}{DecorView} 继承\color{red}{FrameLayout}

    第二步,其实就是将传进来的contentView布局资源文件Id解析,添加到DecorView中的基础布局文件的FrameLayout中,及findViewById找到id为\color{red}{ID\_ANDROID\_CONTENT}的FrameLayout

    附上几个关键类的关系图:

    微信图片_20200322151133.png

    附上视图结构图:

    image.png

    总结: View是如何被添加到窗口上?

    1.创建顶层布局容器DecorView

    2.在顶层布局中加载基础布局ViewGroup

    3.将ContentView添加到基础布局中的FrameLayout中

    相关文章

      网友评论

          本文标题:#Android View是如何被添加到窗口上?

          本文链接:https://www.haomeiwen.com/subject/ibpmyhtx.html