view的流程
1、概述
view的三大流程:测量measure、布局layout、绘制draw
viewGroup:
measure:先测子view再测viewGroup本身
layout:先布局自己再布局子view
draw:先画自己再画子view
2、measure
measure过程比较复杂,主要就是MeasureSpec
MeasureSpec 是个整形,由两部分合成,一个是specSize 一个是specMode
specMode:测量模式
specSize:测量模式下的规格大小
specMode EXACTLY
精确模式,父容器已经测出子view的大小。view的大小就是specSize
对应:layoutParams match_parent 和 具体的数值 dp pxspecMode AT_MOST
父容器指定一个可用大小spectSize view不能大于该值。
对应:layoutParams wrap_contentspecMode UNSPECIFIED
父容器不对view有任何限制,要多大给多大,一般是系统内部使用,可以不考虑
2.2 获取view的width height
在项目中每个android 开发者应该都遇到过在onCreate()函数中 view.getwidth = 0的情况
因为view的measure流程和activity的生命周期方法不是同步执行的,因此无法保证activity执行了onCreate,onStart, onResume时 某个view 已经测量完毕
比较简单的获取方式:
2.2.1post获取,比较方便的方式
view.post(new Runable(){
@override
public void run(){
int width = view.getMeasureWidth();
)
以下几种测量方法例子摘自:http://www.tuicool.com/articles/nAzAbq
2.2.2用ViewTreeObserver 监听
ViewTreeObserver vto = myImageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
//要remove 否则调用多次
myImageView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myImageView.getMeasuredHeight();
int width = myImageView.getMeasuredWidth();
Log.d("===PreDrawListener", "PreDrawListener..myImageView " +
"height:" + height + " ,width:" + width);
return true;
}
});
或者
ViewTreeObserver vto = myImageView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
myImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
Log.d("===OnGlobalLayout", "OnGlobalLayoutListener..myImageView " +
"height:" + myImageView.getHeight() + " ,width:" + myImageView.getWidth());
}
});
2.2.3手动测量
private int measure(View view) {
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
view.measure(w, h);
//int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
return width;
}
3、layout
布局view的位置:上下左右四个点
layout 方法确定view本身位置
onlayout方法确定子view位置
layout里调用onlayout
4、draw
- 绘制背景
- 绘制自己(onDraw)
- 绘制子view(dispatchDraw)
- 绘制装饰(onDrawScrollBar)