zoukankan      html  css  js  c++  java
  • View 中 onMeasure

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

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

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

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

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

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

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

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

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

    实例,也比较好理解.

     
      @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));
     }
     
     /**
      * 高度
      * @param heightMeasureSpec
      * @return
      */
     private int measureHeight(int heightMeasureSpec) {
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);//父的空间大小
        int h = bitmap.getHeight();  //图片的高度
        int result = 0 ;
        if (specMode == MeasureSpec.EXACTLY) {//父为 wrap_content
           result = Math.min(h, specSize);
        }else if(specMode == MeasureSpec.AT_MOST){//父为fill_parent
            result = specSize;
        } else {
            result = specSize;
           }
           return result;
     }

      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是一个大小跟模式的组合值.一共有三种模式.

     (1)UPSPECIFIED :父容器对于子容器没有任何限制,子容器想要多大就多大.
     
     (2) EXACTLY 父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间
     
     (3) AT_MOST 子容器可以是声明大小内的任意大小.
     
    MeasureSpec是View类下的静态公开类,MeasureSpec中的值作为一个整型是为了减少对象的分配开支.此类用于

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

     
  • 相关阅读:
    异常处理机制中的return关键字
    QuickHit 项目
    kali2.0升级
    sslscan
    RC4弱密码套件检测
    CVE-2017-11882漏洞复现
    应急响应小总结
    服务器日志分析
    《x86汇编语言:从实模式到保护模式 》学习笔记之:第一次编写汇编语言
    nasm不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/zhongle/p/2660170.html
Copyright © 2011-2022 走看看