我们在自定义控件的时候,通常会涉及到测量的问题,onMeasure方法就是让我们的控件测量自身的一个方法,这里给出系统自带的一个现成的方法:

1.一次测量所有的孩子

protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {        final int size = mChildrenCount;        final View[] children = mChildren;        for (int i = 0; i < size; ++i) {            final View child = children[i];            if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {                measureChild(child, widthMeasureSpec, heightMeasureSpec);            }        }}
适应于所有孩子的宽和高都一致的情况,方法中的参数是你作为父容器,推荐给孩子的宽和高极其计算模式


2.一次测量一个孩子

protected void measureChild(View child, int parentWidthMeasureSpec,            int parentHeightMeasureSpec) {        final LayoutParams lp = child.getLayoutParams();        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,                mPaddingLeft + mPaddingRight, lp.width);        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,                mPaddingTop + mPaddingBottom, lp.height);        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);}

这个方法用于测量一个孩子,其实第一个方法里面就是用了这个方法.第一个方法比较简便,但是第二个方法比较灵活,可以让每一个孩子的宽和高都不一样,参数不再做解释,应该都看得懂

博客发现一个容易引起误解的地方:就是这个方法所使用的参数名字,parentWidth....这样子的参数意思就是说父容器宽的Measure 或者 高的Measure 而这里的用处完全是孩子用到的,所以这里博客认为这个参数的名称起的有问题,比较容易引起误解,如果哪位大大知道我说的有错误,还请指正,欢迎留言给我!


3.获取一个MeasureSpec对象(MeasureSpec就是保存计算模式和值的一个值,一个值中可以解析出两个值)

public static int getChildMeasureSpec(int spec, int padding, int childDimension) {//......}
由于代码比较长,故不贴出中间的实现了,这个方法是根据推荐的spec(宽或高计算模式和宽或高的值),padding(左边距+右边距),chileDimension(孩子的宽或者高的值,可以是LayoutParams.WRAP_CONTENT(包裹),LayoutParams.MATCH_PARENT(填充))


4. 获取容器本身的宽或者高

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;}

这个方法和第三个是类似的,只不过第三个针对的是孩子,也就是容器中的View对象,这个方法针对的是自身,也就是容器本身,代码也比较简单,其实就是帮你计算容器本身的宽和高,如果是包裹的时候,就采用传入的第一个参数,所以第一个参数size是容器自身包裹的时候用到的,而容器自身包裹的宽或者高的值就是根据你这个自定义控件自身而定.也就是在包裹的时候size就需要你自己计算出来

更多相关文章

  1. android Listview中button 和Listview可同时点击的方法
  2. android添加后门的一种方法
  3. android 中 unable to start service 错误解决方法
  4. Android之Servic的生命周期和调用方法
  5. Android中fragment A里面点击button跳转到fragment B实现方法
  6. Android Activity之间传递图片(Bitmap)的方法
  7. 【android】ORMLite框架 的使用方法---给你的数据库操作插上翅膀

随机推荐

  1. android实现垂直方向跑马灯效果
  2. Android(安卓)如何关闭Navigation Bar
  3. Android(安卓)4 游戏高级编程(第2版)
  4. Android(安卓)Material Design 组件集合D
  5. 安卓缓存-LruCache介绍
  6. [AndroidTips]Android中系统自带的锁:Walk
  7. Android知识要点整理(2)----- 应用资源
  8. Android零散知识点积累
  9. SDK大全2的读书笔记
  10. 如何使用SQLiteOpenHelper