onMeasure方法在控件的父元素正要放置它的子控件时调用.它会问一个问题,“你想要用多大地方啊?”,而后传入两个参数——widthMeasureSpec和heightMeasureSpec.
它们指明控件可得到的空间以及关于这个空间描述的元数据.
比返回一个结果要好的方法是你传递View的高度和宽度到setMeasuredDimension方法里.
接下来的代码片断给出了如何重写onMeasure.注意,调用的本地空方法是来计算高度和宽度的.它们会译解widthHeightSpec和heightMeasureSpec值,并计算出合适的高度和宽度值.
java代码:
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- int measuredHeight = measureHeight(heightMeasureSpec);
- int measuredWidth = measureWidth(widthMeasureSpec);
- setMeasuredDimension(measuredHeight, measuredWidth);
- }
-
- private int measureHeight(int measureSpec) {
-
-
- // Return measured widget height.
- }
-
- private int measureWidth(int measureSpec) {
-
- // Return measured widget width.
- }
-
复制代码
边界参数——widthMeasureSpec和heightMeasureSpec ,效率的缘由以整数的方式传入。在它们使用以前,首先要作的是使用MeasureSpec类的静态方法getMode和getSize来译解,以下面的片断所示:
java代码:
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
复制代码
依据specMode的值,若是是AT_MOST,specSize 表明的是最大可得到的空间;若是是EXACTLY,specSize 表明的是精确的尺寸;若是是UNSPECIFIED,对于控件尺寸来讲,没有任何参考意义。
当以EXACT方式标记测量尺寸,父元素会坚持在一个指定的精确尺寸区域放置View。在父元素问子元素要多大空间时,AT_MOST指示者会说给我最大的范围。在不少状况下,你获得的值都是相同的。
在两种状况下,你必须绝对的处理这些限制。在一些状况下,它可能会返回超出这些限制的尺寸,在这种状况下,你能够让父元素选择如何对待超出的View,使用裁剪仍是滚动等技术。
接下来的框架代码给出了处理View测量的典型实现:
java代码:
- @Override
-
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- int measuredHeight = measureHeight(heightMeasureSpec);
-
- int measuredWidth = measureWidth(widthMeasureSpec);
-
- setMeasuredDimension(measuredHeight, measuredWidth);
-
- }
-
- private int measureHeight(int measureSpec) {
-
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- // Default size if no limits are specified.
-
- int result = 500;
- if (specMode == MeasureSpec.AT_MOST){
-
- // Calculate the ideal size of your
- // control within this maximum size.
- // If your control fills the available
- // space return the outer bound.
-
- result = specSize;
- }
- else if (specMode == MeasureSpec.EXACTLY){
-
- // If your control can fit within these bounds return that value.
- result = specSize;
- }
-
- return result;
- }
-
- private int measureWidth(int measureSpec) {
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- // Default size if no limits are specified.
- int result = 500;
- if (specMode == MeasureSpec.AT_MOST){
- // Calculate the ideal size of your control
- // within this maximum size.
- // If your control fills the available space
- // return the outer bound.
- result = specSize;
- }
-
- else if (specMode == MeasureSpec.EXACTLY){
- // If your control can fit within these bounds return that value.
-
- result = specSize;
- }
-
- return result;
- }