Android view的绘制流程(一)
2014-04-17 15:42
316 查看
整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为根据之前
设置的状态,判断是否需要重新计算视图大小(measure)、是否重新需要安置视图的位置(layout)、以及是否需要重绘(draw),其框架过程如下:
![](http://www.linuxidc.com/upload/2012_01/120109192481052.gif)
接下来温习一下整个View树的结构,对每个具体View对象的操作,其实就是个递归的实现。
![](http://www.linuxidc.com/upload/2012_01/120109192481051.gif)
本文相关代码下载
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2012年资料/1月/9日/Android中View绘制流程以及invalidate()等相关方法分析/
每个View的控件的实际宽高都是由父视图和本身视图决定的。
具体的调用链如下:
ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调View/ViewGroup
对象的onMeasure()方法,该方法实现的功能如下:
1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:
mMeasuredHeight)和宽(对应属性:mMeasureWidth) ;
2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。
2.1 对每个子视图的measure()过程,是通过调用父类ViewGroup.java类里的measureChildWithMargins()方法去实现,
该方法内部只是简单地调用了View对象的measure()方法。(由于measureChildWithMargins()方法只是一个过渡层,更简单
的做法是直接调用View对象的measure()方法)
整个measure调用流程就是个树形的递归过程
measure函数原型为 View.java 该函数不能被重载
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
//....
//回调onMeasure()方法
onMeasure(widthMeasureSpec, heightMeasureSpec);
//more
}
为了大家更好的理解,采用“二B程序员”的方式利用伪代码描述该measure流程
// measure()过程 ViewRoot.java
// 发起measure()的"发号者"在ViewRoot.java里的performTraversals()方法, mView.measure()
private void performTraversals(){
//...
View mView ;
mView.measure(h,l) ;
//....
}
//回调View视图里的onMeasure过程
private void onMeasure(int height , int width){
//设置该view的实际宽(mMeasuredWidth)高(mMeasuredHeight)
//1、该方法必须在onMeasure调用,否者报异常。
setMeasuredDimension(h , l) ;
//2、如果该View是ViewGroup类型,则对它的每个子View进行measure()过程
int childCount = getChildCount() ;
for(int i=0 ;i<childCount ;i++){
//2.1、获得每个子View对象引用
View child = getChildAt(i) ;
//整个measure()过程就是个递归过程
//该方法只是一个过滤器,最后会调用measure()过程 ;或者 measureChild(child , h, i)方法都
measureChildWithMargins(child , h, i) ;
//其实,对于我们自己写的应用来说,最好的办法是去掉框架里的该方法,直接调用view.measure(),如下:
//child.measure(h, l)
}
}
//该方法具体实现在ViewGroup.java里 。
protected void measureChildWithMargins(View v, int height , int width){
v.measure(h,l)
}
设置的状态,判断是否需要重新计算视图大小(measure)、是否重新需要安置视图的位置(layout)、以及是否需要重绘(draw),其框架过程如下:
![](http://www.linuxidc.com/upload/2012_01/120109192481052.gif)
接下来温习一下整个View树的结构,对每个具体View对象的操作,其实就是个递归的实现。
![](http://www.linuxidc.com/upload/2012_01/120109192481051.gif)
本文相关代码下载
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2012年资料/1月/9日/Android中View绘制流程以及invalidate()等相关方法分析/
流程一: mesarue()过程
主要作用:为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性:mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。
具体的调用链如下:
ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调View/ViewGroup
对象的onMeasure()方法,该方法实现的功能如下:
1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:
mMeasuredHeight)和宽(对应属性:mMeasureWidth) ;
2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。
2.1 对每个子视图的measure()过程,是通过调用父类ViewGroup.java类里的measureChildWithMargins()方法去实现,
该方法内部只是简单地调用了View对象的measure()方法。(由于measureChildWithMargins()方法只是一个过渡层,更简单
的做法是直接调用View对象的measure()方法)
整个measure调用流程就是个树形的递归过程
measure函数原型为 View.java 该函数不能被重载
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
//....
//回调onMeasure()方法
onMeasure(widthMeasureSpec, heightMeasureSpec);
//more
}
为了大家更好的理解,采用“二B程序员”的方式利用伪代码描述该measure流程
// measure()过程 ViewRoot.java
// 发起measure()的"发号者"在ViewRoot.java里的performTraversals()方法, mView.measure()
private void performTraversals(){
//...
View mView ;
mView.measure(h,l) ;
//....
}
//回调View视图里的onMeasure过程
private void onMeasure(int height , int width){
//设置该view的实际宽(mMeasuredWidth)高(mMeasuredHeight)
//1、该方法必须在onMeasure调用,否者报异常。
setMeasuredDimension(h , l) ;
//2、如果该View是ViewGroup类型,则对它的每个子View进行measure()过程
int childCount = getChildCount() ;
for(int i=0 ;i<childCount ;i++){
//2.1、获得每个子View对象引用
View child = getChildAt(i) ;
//整个measure()过程就是个递归过程
//该方法只是一个过滤器,最后会调用measure()过程 ;或者 measureChild(child , h, i)方法都
measureChildWithMargins(child , h, i) ;
//其实,对于我们自己写的应用来说,最好的办法是去掉框架里的该方法,直接调用view.measure(),如下:
//child.measure(h, l)
}
}
//该方法具体实现在ViewGroup.java里 。
protected void measureChildWithMargins(View v, int height , int width){
v.measure(h,l)
}
相关文章推荐
- AndroidView绘制流程分析及自定义View、ViewGroup进阶
- Android中View绘制流程以及invalidate()等相关方法分析
- 【转】深入理解Android之View的绘制流程
- Android View绘制三大流程探索及常见问题
- Android中View绘制流程以及invalidate()等相关方法分析
- Android中View绘制流程以及invalidate()等相关方法分析
- Android View绘制流程
- Android的View绘制流程
- Android中View绘制流程以及invalidate()等相关方法分析(转)
- Android 自定义View、ViewGroup(二)之绘制流程
- Android应用层View绘制流程与源码分析
- Android视图View绘制流程及源码分析
- 深入理解Android之View的绘制流程
- 关于Android中View的绘制流程的学习(一)
- Android中View绘制流程以及invalidate()等相关方法分析
- Android应用层View绘制流程与源码分析
- Android视图绘制流程完全解析,带你一步步深入了解View(二)
- Android View绘制流程
- Android View绘制的三大流程
- Android组件View绘制流程原理分析