美文网首页Android进阶之路Android开发经验谈Android技术知识
UI绘制流程及原理:View显示到屏幕的流程

UI绘制流程及原理:View显示到屏幕的流程

作者: space0o0 | 来源:发表于2019-09-29 11:35 被阅读0次

    Activity的界面添加到屏幕的流程

    1、创建顶层布局容器DecorView(FrameLayout)
    2、在DecorView中加载/基础布局/得到内部的ViewGroup
    3、在/基础布局/中添加自己写的ContentView(即Activity的界面)

    01.png

    具体流程(源码分析:方法的调用)

    • Activity中调用setContentView()方法
    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }
    

    getWindow():PhoneWindow对象

    • 调用PhoneWindow对象的setContentView()方法
    //PhoneWindow.java
    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();//调用方法初始化Decor
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }
        //无关代码
    }
    
    • installDecor()方法:创建decorVIew
    //PhoneWindow.java
    private void installDecor() {
        mForceDecorInstall = false;
        if (mDecor == null) {
          mDecor = generateDecor(-1);//返回DecorView
            //无关代码
        }
        //无关代码
    }
    
    

    调用generateDecor()方法,返回一个DecorView对象
    DecorView就是顶层布局,他是一个FrameLayout,第一个父布局产生!!!

    • installDecor()方法:创建mContentParent(ViewGroup)
    //PhoneWindow.java
    private void installDecor() {
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);//创建基础布局方法
            //无关代码
        }
        //无关代码
    }
    

    mContentParent:一个ViewGroup对象,从字面上就看出是我们要加载content的parent布局(ViewGroup)

    • generateLayout()方法:返回mContentParent(ViewGroup)
    // Inflate the window decor.
    int layoutResource;
    ...
    //layoutResource根据不同的显示效果,赋值不同的布局文件
    ...
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    ...
    return contentParent;
    

    赋值layoutResource(布局文件),再把该布局文件添加到DecorView中,第二个基础布局创建完成!!!

    不同的布局文件中总是存在一个id叫:/com.android.internal.R.id.content/ 的ViewGroup。

    contentParent通过findViewById找到该id的控件,并返回。

    DecorView(FrameLayout)中嵌套一个基础布局
    基础布局中包含一个id(/com.android.internal.R.id.content/)的ViewGroup

    • mContentParent中添加Activity的的布局文件
    //PhoneWindow.java
    @Override
    public void setContentView(int layoutResID) {
            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作为parent,在解析Activity的layout中传入。最终显示到屏幕上。

    总结

    创建DecorView:PhoneWindow对象 -> installDecor() -> generateDecor() -> 得到DecorView

    创建mContentParent:generateLayout() -> decorView关联基础布局(xml) -> findViewById(R.id.content) -> 得到mContentParent

    Activity的布局放入mContentParent:setContentView()中,inflate(layoutResID,mContentParent)

    相关文章

      网友评论

        本文标题:UI绘制流程及原理:View显示到屏幕的流程

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