今天学习android自定义组件:docs/guide/topics/ui/custom-components.html

其中有两个对布局界面影响很的方法,onDraw(),和onMeasure().

onDraw()比较好理解.onMeasure()就比较难理解一些,也更复杂些 ,引用文档中的说法就是:

onMeasure() is a little more involved. 其实还有另一个方面的原因就是我对这个单词measure不是很知道,然后果了下词典,就放了下心,确实是测量的意思.

实现onMeasure()方法基本需要完成下面三个方面的事情(最终结果是你自己写相应代码得出测量值并调用view的一个方法进行设置,告诉给你的view安排位置大小的父容器你要多大的空间.):

1.传递进来的参数,widthMeasureSpec,和heightMeasureSpec是你对你应该得出来的测量值的限制.

The overidden onMeasure() method is called with width and height measure specifications(widthMeasureSpec and heightMeasureSpec parameters,both are integer codes representing dimensions) which should be treated as requirements for the restrictions on the width and height measurements you should produce.

2. 你在onMeasure计算出来设置的width和height将被用来渲染组件.应当尽量在传递进来的width和height 声明之间.

虽然你也可以选择你设置的尺寸超过传递进来的声明.但是这样的话,父容器可以选择,如clipping,scrolling,或者抛出异常,或者(也许是用新的声明参数)再次调用onMeasure()

Your component's onMeasure() method should calculate a measurement width and height which will be required to render the component.it should try to stay within the specified passed in.although it can choose to exceed them(in this case,the parent can choose what to do,including clipping,scrolling,throwing an excption,or asking the onMeasure to try again,perhaps with different measurement specifications).

3.一但width和height计算好了,就应该调用View.setMeasuredDimension(int width,int height)方法,否则将导致抛出异常.

Once the width and height are calculated,the setMeasureDimension(int width,int height) method must be called with the calculated measurements.Failure to do this will result in an exceptiion being thrown

在Android提提供的一个自定义View示例中(在API demos 中的 view/LabelView)可以看到一个重写onMeasure()方法的

实例,也比较好理解.

/**

* @see android.view.View#measure(int, int)

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

setMeasuredDimension(measureWidth(widthMeasureSpec),

measureHeight(heightMeasureSpec));

}

/**

* Determines the width of this view

* @param measureSpec A measureSpec packed into an int

* @return The width of the view, honoring constraints from measureSpec

*/

private int measureWidth(int measureSpec) {

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.EXACTLY) {

// We were told how big to be

result = specSize;

} else {

// Measure the text

result = (int) mTextPaint.measureText(mText) + getPaddingLeft()

+ getPaddingRight();

if (specMode == MeasureSpec.AT_MOST) {

// Respect AT_MOST value if that was what is called for by measureSpec

result = Math.min(result, specSize);

}

}

return result;

}

直接看measureWidth()

首先看到的是参数,分别代表宽度和高度的MeasureSpec

android2.2文档中对于MeasureSpec中的说明是:

一个MeasureSpec封装了从父容器传递给子容器的布局需求.

每一个MeasureSpec代表了一个宽度,或者高度的说明.

一个MeasureSpec是一个大小跟模式的组合值.一共有三种模式.

A MeasureSpec encapsulates the layout requirements passed from parent to child Each MeasureSpec represents a requirement for either the width or the height.A MeasureSpec is compsized of a size and a mode.There are three possible modes:

(1)UPSPECIFIED :父容器对于子容器没有任何限制,子容器想要多大就多大.

UNSPECIFIED The parent has not imposed any constraint on the child.It can be whatever size it wants

(2) EXACTLY

父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.

EXACTLY The parent has determined and exact size for the child.The child is going to be given those bounds regardless of how big it wants to be.

(3) AT_MOST

子容器可以是声明大小内的任意大小.

AT_MOST The child can be as large as it wants up to the specified size

MeasureSpec是View类下的静态公开类,MeasureSpec中的值作为一个整型是为了减少对象的分配开支.此类用于

将size和mode打包或者解包为一个整型.

MeasureSpecs are implemented as ints to reduce object allocation.This class is provided to pack and unpack the size,mode tuple into the int

我比较好奇的是怎么样将两个值打包到一个int中,又如何解包.

MeasureSpec类代码如下 :(注释已经被我删除了,因为在上面说明了.)

public static class MeasureSpec {

private static final int MODE_SHIFT = 30;

private static final int MODE_MASK = 0x3 << MODE_SHIFT;

public static final int UNSPECIFIED = 0 << MODE_SHIFT;

public static final int EXACTLY = 1 << MODE_SHIFT;

public static final int AT_MOST = 2 << MODE_SHIFT;

public static int makeMeasureSpec(int size, int mode) {

return size + mode;

}

public static int getMode(int measureSpec) {

return (measureSpec & MODE_MASK);

}

public static int getSize(int measureSpec) {

return (measureSpec & ~MODE_MASK);

} }

我无聊的将他们的十进制值打印出来了:

mode_shift=30,mode_mask=-1073741824,UNSPECIFIED=0,EXACTLY=1073741824,AT_MOST=-2147483648

然后觉得也应该将他们的二进制值打印出来,如下:

mode_shift=11110, // 30

mode_mask=11000000000000000000000000000000,

UNSPECIFIED=0,

EXACTLY=1000000000000000000000000000000,

AT_MOST=10000000000000000000000000000000

MODE_MASK = 0x3 << MODE_SHIFT //也就是说MODE_MASK是由11左移30位得到的.因为Java用补码表示数值.最后得到的值最高位是1所以就是负数了

对于上面的数值我们应该这样想,不要把0x3看成3而要看成二进制的11,

而把MODE_SHIFF就看成30.那为什么是二进制 的11呢?

呢,因为只有三各模式,如果有四种模式就是111了因为111三个位才可以有四种组合对吧.

我们这样来看,

UNSPECIFIED=00000000000000000000000000000000,

EXACTLY=01000000000000000000000000000000,

AT_MOST=10000000000000000000000000000000

也就是说,0,1,2

对应   00,01,10

当跟11想与时  00 &11 还是得到 00,11&01 -> 01,10&

我觉得到了这个份上相信,看我博客的也都理解了.

return (measureSpec & ~MODE_MASK);应该是 return (measureSpec & (~MODE_MASK));

android onmeasure方法的参数,android中onMeasure初看,深入理解布局之一!相关推荐

  1. android获取方法的参数,Android 获取 sn 详解,以及测试报告~

    1.小结: 1.Android 9及以上无法获取sn,Android 9以下不需要权限即可获取 2.获取到的参数相对稳定不变 3.不同手机参数长度可能不同 补充:新增获取方法:Build.getSer ...

  2. android hide方法 末班,android 如何引用@hide(隐藏)的类,方法和常量?

    最近在处理SD卡的读写问题,本地Elipse能跑的程序提交到服务器上的时候,报错,找不到import的类,还有一些方法也是找不到,利用sourceInsight搜了源码发现都是用了@hide标记的类和 ...

  3. android volley 上传图片 和参数,android Volley 上传文件上传图片

    android volley 实现上传文件功能 Volley不解释了吧, android 官方的一个网络请求库. 源代码的地址在: git@github.com:com314159/VolleyMul ...

  4. python get方法列表参数_python中requests库get方法带参数请求

    起因是想爬五等分的花嫁的漫画.这是其中的一个坑 先上代码 data={ 'cid':567464, 'page':, 'key':'', 'language':1, 'gtk':6, '_cid':5 ...

  5. python get方法请求参数_python中requests库get方法带参数请求

    起因是想爬五等分的花嫁的漫画.这是其中的一个坑 先上代码 data={'cid':567464,'page':1,'key':'','language':1,'gtk':6,'_cid':567464 ...

  6. android settext里面的参数,Android中TextView的SetText()方法注意事项

    忙活了一个下午才研究出来的.... 学习Android的Intent时候跟着Mars老师做简单的乘法程序,在第一个activity输入两个正整数,通过一个intent跳转到第二个intent,在第二个 ...

  7. android settext里面的参数,Android: fragment 中有时textview.setText()不起效

    如题. 出现场景: 送礼物的界面一个gridview 显示不同礼物item,每送出去一个,对应要更新展示的金币余额. 在一个fragment里面调用控件的setText()的时候,偶尔不起作用或者明显 ...

  8. android class newinstance 构造函数 参数,android Fragment里的newInstance和构造函数

    最近用android studio创建fragment时,总是默认会创建一个静态工厂函数 public static InstalledAppFragment newInstance() { Inst ...

  9. android调用webservice传参数,android调用webservice接口获取信息

    我的有一篇博客上讲了如何基于CXF搭建webservice,service层的接口会被部署到tomcat上,这一篇我就讲一下如何在安卓中调用这些接口传递参数. 1.在lib中放入ksoap2的jar包 ...

最新文章

  1. python曲线拟合笔记
  2. 提高PHP性能的53个技巧
  3. Linux centos7 配置用户自动登录
  4. Android -- 自定义ScrollView实现放大回弹效果
  5. java数组重复_JAVA数组去除重复数据
  6. 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题
  7. iOS版本更新与集成百度地图
  8. 站长之家bbs.chinaz.com宣布将于2018年7月15日永久关站
  9. 模拟iic和硬件iic区别_技术货:IIC总线的FPGA实现
  10. 阿里云网盘内测_叫板百度网盘?阿里云网盘内测中,下载速度是亮点
  11. Unity LitJson的读写使用
  12. 【Godot】项目结构设计
  13. 各种字体下载地址和移动端支持字体简析
  14. Mysql的explain,你真的会用吗?
  15. Oracle LiveLabs实验:Oracle Database Hybrid Active Data Guard
  16. 加了索引,mysql查询就一定会用吗?
  17. GIS中墨卡托与WGS 84的瓦片编号计算方法
  18. 特岗计算机考试面试,你应该知道的特岗教师面试注意事项!快来收藏吧!
  19. latex大括号 多行公式_问题百出的MathType公式编辑器,会有替代品吗?
  20. 数字电路中的基础电路结构

热门文章

  1. 微信“跳一跳”高分技巧
  2. 性能优化之三——手机发热
  3. AToken全观:V神发话了,支持钱包开发者收取额外交易费
  4. 快速学习-Sleuth--链路追踪
  5. 一文看懂ingress nginx实现灰度发布和蓝绿发布过程
  6. 如何使用Openlayers 3加载谷歌离线地图
  7. 【MySQL 优化】单一索引与复合索引
  8. Unity3D -- 调用手机端发送邮件功能
  9. 对焦与变焦的区别(the difference of focus and zoom)
  10. 第九十三章 SQL函数 LTRIM