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

view的流程

1、概述

view的三大流程:测量measure、布局layout、绘制draw

viewGroup:
measure:先测子view再测viewGroup本身
layout:先布局自己再布局子view
draw:先画自己再画子view

2、measure

measure过程比较复杂,主要就是MeasureSpec
MeasureSpec 是个整形,由两部分合成,一个是specSize 一个是specMode
specMode:测量模式
specSize:测量模式下的规格大小

  1. specMode EXACTLY
    精确模式,父容器已经测出子view的大小。view的大小就是specSize
    对应:layoutParams match_parent 和 具体的数值 dp px

  2. specMode AT_MOST
    父容器指定一个可用大小spectSize view不能大于该值。
    对应:layoutParams wrap_content

  3. 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

  1. 绘制背景
  2. 绘制自己(onDraw)
  3. 绘制子view(dispatchDraw)
  4. 绘制装饰(onDrawScrollBar)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值