美文网首页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