canvas教程

view的绘制流程.doc

字号+ 作者:H5之家 来源:H5之家 2017-05-15 18:03 我要评论( )

View 的绘制流程 View 的绘制是从 ViewRoot 的 performTraversals() 开始的,该函数做的执行过程主要是根据之前设置的状态, 判断是否重新计算视图大小(measure)

文档介绍:
View 的绘制流程 View 的绘制是从 ViewRoot 的 performTraversals() 开始的,该函数做的执行过程主要是根据之前设置的状态, 判断是否重新计算视图大小(measure) 、是否重新放置视图的位置(layout) 、以及是否重绘(draw) ,其核心也就是通过判断来选择顺序执行这三个方法中的哪个。 performTraversals() 这个方法完成了对顶级 View 的 measure , layout , draw 三个过程, 其中又会分别对子 View 进行遍历,实现整个 View 的绘制。[java] view plain copy 在 CODE 上查看代码片派生到我的代码片 private void performTraversals() { ...... //lp.width 和 lp.height 在创建 ViewGroup 实例时等于 MATCH_PARENT int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); ...... mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); ...... mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight()); ...... mView.draw(canvas); ...... } 在第 5~6 行获取了根视图的 MeasureSpec , size 等于屏幕的大小, mode 是 At_Most 。接着就调用 measure() 方法进行测量,所以首先看看 measure 的过程。 View 的 measure 过程 measure() 方法[java] view plain copy 在 CODE 上查看代码片派生到我的代码片 public final void measure(int widthMeasureSpec, int heightMeasureSpec) { ...... // measure ourselves, this should set the measured dimension flag back onMeasure(widthMeasureSpec, heightMeasureSpec); ...... } 其中传入的两个参数信息是宽高的参数信息,用于计算实际宽高,它真实的测量是在 onMeasure(int, int) 中完成的, 并且可以看到 measure() 方法是一个 final 方法, 所以不能重写, 所以我们只需要重写 onMeasure() 方法。至于 widthMeasureSpec 和 heightMeasureSpec 从哪里来的,下面会分析到。 onMeasure() 方法[java] view plain copy 在 CODE 上查看代码片派生到我的代码片 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); } 这个方法里面很简单, 就调用了 setMeasuredDimension() 方法, 如果我们重写 onMeasure() 方法必须去调用这个 setMeasuredDimension() 方法, 它去存储了 view 的宽高的测量信息。这里传递进来的宽高信息都是用 MeasureSpec 存储的,先看看这个 MeasureSpec MeasureSpec 它是一个 32 位的 int 值,高两位代表模式,低 30 位代表大小,模式有以下三种: UNSPECIFIED :父容器对这个 view 没有任何限制,可以得到任意它想要的大小 EXACTLY :父容器已经决定了 View 的精确大小,也就是父容器的 SpecSize 的大小,相当于我们的 match_parent AT_MOST : 父容器指定了一个大小 SpecSize , View 不能超过这个大小, 具体根据实际情况, 相当于 wrap_content 一个 View 的 MeasureSpec 确定了,再通过 onMeasure() 方法,那么它的大小也就确定了,一个 Vie w的 MeasureSpe c 的确定是由父容器的 MeasureSpe c 和它自身的 LayoutParam s 共同决定的。 getDefaultSize() 方法[java] view plain copy 在 CODE 上查看代码片派生到我的代码片 public static int getDefaultSize(int size, int measureSpec) { int result = size; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.UNSPECIFIED: result = size; break; case MeasureSpec.AT_MOST: case MeasureSpec.EXACTLY: result = specSize; break; } return result; } 这个方法是根据传入的 size 和父类的 MeasureSpec 来返回一个默认的大小。上面可以看到这里的 size 是通过 getSuggestedMinimumWidth 或者 getSuggestedMinimumHeight 获取的, 再通过 MeasureSpec 计算出它的大小,这里当 mode 为 At_Most 和 Exactly, 返回的都是 specSize 。第 3~4 行,根据父类的 MeasureSpec 来计算出其中的 mode 和 size 。第 6~14 行,用一个 switch 语句根据父类不同的 mode 来返回不同的大小。[java] view plain copy 在 CODE 上查看代码片派生到我的代码片 protected int getSuggestedMinimumWidth() { return (mBackground == nu

1

内容来自淘豆网转载请标明出处.

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • iOS开发技巧(系列九:UIView截屏)

    iOS开发技巧(系列九:UIView截屏)

    2017-05-10 10:05

  • HTML5中使用canvas绘制圆形

    HTML5中使用canvas绘制圆形

    2017-05-09 10:05

  • ViewPager onPageChangeListener总结

    ViewPager onPageChangeListener总结

    2017-05-08 16:00

  • 8.2.8 drawRoundRect方法:绘制圆角矩形

    8.2.8 drawRoundRect方法:绘制圆角矩形

    2017-05-05 12:04

网友点评
n