您的位置:首页 > 其它

view的流程(测量,布局,绘制)

2016-02-24 14:38 302 查看

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 px

specMode AT_MOST

父容器指定一个可用大小spectSize view不能大于该值。

对应:layoutParams wrap_content

specMode 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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息