android View绘制流程

android的View的绘制流程大概就如同我们作画一样,分为以下几步:

1. 测量出每个view的大小。

2.根据上一步测量得到的大小,确定view绘制的坐标位置。

3.有了具体的位置及view大小,开始绘制view。

我们的Activity在创建的时候就会对应的创建一个window,用于展示我们需要展示的view,可能android为了统一界面风格吧,在activity创建的时候就给安排好了主要的三个部分,statusbar,actionbar, content,其中actionbar和content都是decorview的子View。

而所有的view的展示都依赖于在activity创建时创建的phonewindow,而view添加到phonewindow的过程又依赖于ViewRootImpl,viewrootImpl通过调用performTranversals方法,将view添加到window上。

在performTranversal方法中会依次调用mView的measure,layout,draw方法,这三个方法也就完成了我们上面提到的那三点。

measue方法,用于测量view的大小,这里view的大小是通过父view的mode及size结合子view layoutparam来确定的,首先会通过迭代的方式,计算得到子View的具体大小,然后再依次向上得到每个父View的大小(对于初始设定了大小的view,并不由其子View决定其大小),最终算出每个view的大小。measue方法是final类型的,子View不可以重写该方法,但是在measure中会调用onMeasure方法,可以重写该方法,来做不同的测量方式,对于我们所熟知的LinearLayout,FrameLayout及RelativeLayout他们都进行了不同的重写,来实现他们的布局特征。

layout方法主要根据在第一步中测量得到的view矩阵,确定每个view所处的坐标位置,在这里view可以重写onlayout方法,不使用之前的测量,固定写死的去布局自己的view,不过意义不大,一般会使用系统默认的。这里同上面一样,对于ViewGroup会迭代的调用其子View的layout方法完成布局。

draw在知道了view的坐标及大小后,这一步就是调用View的draw方法绘制View及其内容和背景。这里同上面一样,View的绘制也是通过迭代的方式,循环的调用子View的draw方法,将所有非Gone的view绘制下来,在绘制的地方有个小细节,View一旦绘制完成后,进行重绘的时候,会判断需要绘制的部分有没有变化,如果没有变化就不再重绘。这一点算是对绘制过程的优化,避免在某个子view更新的时候,重绘整个屏幕。


猜你喜欢

转载自blog.csdn.net/weixin_31706797/article/details/80329600