AndroidUI绘制流程笔记

一、从setContentView(R.layout.activity_main);入手了解UI的绘制起始过程
1.Activity.java

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

2.getWindow()拿到的是Window的实现类PhoneWindow

PhoneWindow源码:

 @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();//②
        }
	……
	mLayoutInflater.inflate(layoutResID, mContentParent);//⑥
    }

    private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();//③生成一个DecorView(继承的FrameLayout)
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);//④
	}
	
    protected ViewGroup generateLayout(DecorView decor) {//⑤
	View in = mLayoutInflater.inflate(layoutResource, null);
        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        mContentRoot = (ViewGroup) in;
    }

在这里插入图片描述

二、measure、layout、draw的三个执行流程

  • 1.View.java类
    measure:测量,测量自己有多大,如果是ViewGroup的话会同时测量里面的子控件的大小
    layout:摆放viewgroup里面的子控件(view是不需要layout的)
    draw:绘制UI

看View.java类的源码:
1.view的requestLayout()方法开始,递归地不断往上找父容器,最终找到DecorView
2.执行了DecorView的ViewRootImp类的performTranversal()方法

3.performTranversal(){

	 // Ask host how big it wants to be
          performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);

	  performLayout(lp, desiredWindowWidth, desiredWindowHeight);

	  performDraw();
}
4.
    private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
        try {
            mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);//测量最后是调用该方法
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
    }

流程如下(如此完成一个view的绘制):
在这里插入图片描述

  • 2.ViewGroup.java类
    ViewGroup的绘制也是首先找到DecorView,接着在DecorView里面找到ViewGroup当作RootView,然后执行如下流程(在RootView里面递归):
    在这里插入图片描述
发布了61 篇原创文章 · 获赞 0 · 访问量 894

猜你喜欢

转载自blog.csdn.net/qq_36828822/article/details/103482912