自定义控件---OnMeasure()方法分析

来源:互联网 发布:淘宝商城女装晚礼服 编辑:程序博客网 时间:2024/05/16 14:03

自定义View的第一步就是要测量Measure控件的大小,所以了解OnMeasure至关重要

首先说说MeasureSpec类

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        }

MeasureSpec是帮助我们测量View的,MeasureSpec是一个32位的int值,其中高2位表示测量模式,后30位表示测量的大小。
测量模式值得一说,搞不清楚的话,很难写好OnMeasure()方法,测量模式分为三种:

  1. EXACTLY:精确模式,将控件的高或者宽设置为match_parent或者具体的数值(如100dp)时,系统采用EXACTLY
  2. AT_MOST,指定为wrap_content时,系统采用AT_MOST,控件随着子控件的内容变化而变化,指的是控件不超过父控件允许的最大尺寸即可
  3. UNSPECIFIED:系统的测量模式,我们不需要了解,自定义控件也用不到这个

如何让你写的控件支持wrap_content

如果你不重写OnMeasure()方法,你写的自定义控件只是支持EXACTLY模式,即只能用具体的数值(如100dp)或者match_parent,是不支持使用wrap_content的(如果你使用了wrap_content的话,效果与match_parent是一样的),如何让你写的控件支持wrap_content呢,重写OnMeasure()即可,以下代码为模板代码:

 //    以下为模板代码,如果不重写onMeasure方法,无法使用wrap_content这个属性,系统不知道该默认什么尺寸,//    就会默认填充整个父布局    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    private int measureWidth(int widthMeasureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {        //如果是EXACTLY模式,测量宽度就是父类传递过来的宽度,(或者说你在xml布局里写的具体的宽度数值或者match_parent)            result = specSize;        } else {            result = DensityUtil.dip2px(context, 200);            if (specMode == MeasureSpec.AT_MOST) {               //如果是AT_MOST模式,测量宽度就是你自己设置的默认宽度与父类传递过来的宽度之间的一个最小值(为什么取最小值呢,因为如果你设置的默认值很大,已经超过了父控件的大小,那么这个控件在父控件里就显示不全了,如果你设置的默认值小于父控件,那么就用你设置的默认值)                result = Math.min(result, specSize);            }        }        return result;    }    private int measureHeight(int heightMeasureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(heightMeasureSpec);        int specSize = MeasureSpec.getSize(heightMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            result = DensityUtil.dip2px(context,200);            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗的爪子肿了怎么办 压缩文件之后显示拒绝访问怎么办 压缩文件解压后全散开了怎么办 dnf助手改名字用完了怎么办 缅甸 佤邦 办中国护照 怎么办? 电脑玩游戏网络延迟大怎么办 qq好友空间锁了怎么办 卡盟进货额不足怎么办 被朋友骗了钱怎么办 联通在学校网差怎么办 前夫把我微信拉黑 孩子的事怎么办 微信好友验证疑似被盗怎么办 我的世界被banip怎么办 dnf深渊宝珠出了怎么办 吞噬魔4个球吃了怎么办 dnf没有支援兵了怎么办 家里没通天然气怎么办 苹果6p16g不够用怎么办 魅蓝手机内存不够用怎么办 3dmax灯光全黑怎么办 高压15o低压1oo怎么办 源码一位乘法中c怎么办 怀孕搬了重东西怎么办 深蹲力量不涨怎么办 ps4连接显示器分辨率低怎么办 大疆失去链接后怎么办 脑袋被锤了几拳怎么办 华为手机变板砖怎么办 电脑网页打开很慢怎么办 网页加载速度太慢.怎么办 cad字显示不出来怎么办 dell笔记本打不开机怎么办 手机系统界面已停止运行怎么办 大石退出菊丸怎么办 word空白页面突然变大了怎么办 高速上车胎爆了怎么办 没有定速巡航跑长途怎么办 惠普笔记本驱动无法安装怎么办 狙击手遇到热追踪导弹怎么办 做完卷腹脖子疼怎么办 医疗设备销售遭遇瓶颈怎么办