View的绘制流程

##1.View的绘制流程
      一般来说View的绘制流程分为三个步骤
      measure(测量),通过measure来确定View的大小(即宽高)
      layout(布局),通过layout来确定View的位置(即在屏幕的具体位置)
      draw(绘制),,通过draw来绘制View所需要显示的内容

##2.从哪里入口
```
```
在开发中,我们通常都会在Activity里写这么一句话setContentView(int)来实现我们想要的布局,页面通常都是依附于Window之上的,而DecorView是窗口上最顶级的视图,DecorView本身也是继承于FrameLayout,它里面的布局如下。

   ![decorView.png](https://upload-images.jianshu.io/upload_images/4092450-293f9ae8c8414e2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
所以我们在调用setContentView的时候,其实就是把我们的布局给添加到R.id.content的布局上面,然后我们在回来View的绘制.
 
##3.ViewRootImp
通过ViewRoot来绘制View,而ViewRoot的实现类为ViewRootImp,当Activity创建完成之后,会将DecorView添加到窗口Window之中,同时会创建ViewRootImp对象,将ViewRootImp和DecorView关联,我们在自定义View的时候调用View.invalidate()或者View.requestLayout()要求View进行重绘的时候,在View的内部会不断的向上查找父布局,直到最外层的DecorView之后,会调用与之关联的ViewRootImp的performTraversals方法,开始真正的绘制View。![View绘制流程.png](https://upload-images.jianshu.io/upload_images/4092450-5a4c6518423c3a74.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

View的绘制流程是从ViewRoot的performTraversals开始的,首先在performMeasure会开始DecorView的measure方法,在measure方法里会调用onMeasure方法,在onMeasure方法会对DecorView的所有子View进行测量,但是父容易怎么测量子容器的大小呢,这个时候其实是将Measure事件传递到子容易,让他自身进行测量,如此反复下去,直接子View是非容器类控件才停止测量,这样,我们的整个视图树才算测量完成。同理,performLayout和performDraw也一样、

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

猜你喜欢

转载自blog.csdn.net/guim_007/article/details/80111383