MeasureSpec
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式。
这个大小的模式,有点难以理解。在系统中组件的大小模式有三种:
1.精确模式(MeasureSpec.EXACTLY)
在这种模式下,尺寸的值是多少,那么这个组件的长或宽就是多少。
2.最大模式(MeasureSpec.AT_MOST)
这个也就是父组件,能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小。
3.未指定模式(MeasureSpec.UNSPECIFIED)
这个就是说,当前组件,可以随便用空间,不受限制。
可能有很多人想不通,一个int型整数怎么可以表示两个东西(大小模式和大小的值),一个int类型我们知道有32位。而模式有三种,要表示三种状 态,至少得2位二进制位。于是系统采用了最高的2位表示模式。如图:
最高两位是00的时候表示"未指定模式"。即MeasureSpec.UNSPECIFIED
最高两位是01的时候表示"'精确模式"。即MeasureSpec.EXACTLY
最高两位是11的时候表示"最大模式"。即MeasureSpec.AT_MOST
很多人一遇到位操作头就大了,为了操作简便,于是系统给我提供了一个MeasureSpec工具类。
这个工具类有四个方法和三个常量(上面所示)供我们使用:
//这个是由我们给出的尺寸大小和模式生成一个包含这两个信息的int变量,这里这个模式这个参数,传三个常量中的一个。
public static int makeMeasureSpec(int size, int mode)
//这个是得到这个变量中表示的模式信息,将得到的值与三个常量进行比较。
public static int getMode(int measureSpec)
//这个是得到这个变量中表示的尺寸大小的值。
public static int getSize(int measureSpec)
//把这个变量里面的模式和大小组成字符串返回来,方便打日志
public static String toString(int measureSpec)
MeasureSpec.EXACTLY:当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。
MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。
因此,在重写onMeasure方法时要根据模式不同进行尺寸计算。下面代码就是一种比较典型的方式:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));
} private int getMeasuredLength(int length, boolean isWidth) {
int specMode = MeasureSpec.getMode(length);
int specSize = MeasureSpec.getSize(length);
int size;
int padding = isWidth ? getPaddingLeft() + getPaddingRight()
: getPaddingTop() + getPaddingBottom();
if (specMode == MeasureSpec.EXACTLY) {
size = specSize;
} else {
size = isWidth ? padding + mWave.length / 4 : DEFAULT_HEIGHT
+ padding;
if (specMode == MeasureSpec.AT_MOST) {
size = Math.min(size, specSize);
}
}
return size;
}
解决ScrollView嵌套ListView和GridView冲突的方法
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
public class MyGridView extends GridView {
private boolean haveScrollbar = true;
public MyGridView(Context context) {
super(context);
}
public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 设置是否有ScrollBar,当要在ScollView中显示时,应当设置为false。 默认为 true
*
* @param haveScrollbars
*/
public void setHaveScrollbar(boolean haveScrollbar) {
this.haveScrollbar = haveScrollbar;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (haveScrollbars == false) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
MeasureSpec的更多相关文章
- Android的onMeasure和onLayout And MeasureSpec揭秘
Android中自定义ViewGroup最重要的就是onMeasure和onLayout方法,都需要重写这两个方法,ViewGroup绘制 的过程是这样的:onMeasure → onLayout → ...
- android学习——MeasureSpec介绍及使用
一.MeasureSpc类说明 SDK的介绍:MeasureSpc类封装了父View传递给子View的布局(layout)要求.每个MeasureSpc实例代表宽度或者高度 它有三种模式:①.UNSP ...
- MeasureSpec介绍
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式. 这个大小的模式,有点难以理解.在系统 ...
- Android开发之View重写相关API-onLayout,onMeasure,MeasureSpec
1.onLayout android.view.ViewGroup protected void onLayout(boolean changed, int l, int t, int r, int ...
- Android中自定义View的MeasureSpec使用
有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/guide/topics/ui/custo ...
- MeasureSpec学习
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式. 这个大小的模式,有点难以理解.在系统 ...
- ANDROID自定义视图——onMeasure流程,MeasureSpec详解
简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局——onLayout():决定View在ViewGroup中的位置 3. ...
- ANDROID定义自己的看法——onMeasure,MeasureSpec源代码 过程 思考具体解释
一个简短的引论: 在他们的定义view什么时候,其实很easy,只需要知道3: 1.測量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGrou ...
- View学习(一)-DecorView,measureSpec与LayoutParams
这段时间在学习android中view的工作原理与自定义View的相关内容,所以未来这这几篇博客都总结一下相关的知识吧. 首先我们要了解和熟悉两个概念,DecorView 与 MeasureSpec. ...
随机推荐
- ubuntu各版本的区别
ubuntu.kubuntu以及xubuntu的区别Ubuntu默认是Gnome:KUbuntu用的是KDE,效果比较炫目,但是系统要求也较高XUbuntu用的是Xface,比较轻量,系统要求较低,推 ...
- 转:PHP中实现非阻塞模式
原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...
- oracle积累继续
选出当天的日期的数据 select * from test_table where to_char(datetime, 'yyyy-mm-dd')=to_char(sysdate,'yyyy-mm-d ...
- 常见的三种Web服务架构
常见的三种Web服务架构 转自http://www.cnblogs.com/bvbook/archive/2008/12/24/1360942.html 相互竞争的服务架构 The Competing ...
- BZOJ 1028 麻将
Description 麻将是中国传统的娱乐工具之一.麻将牌的牌可以分为字牌(共有东.南.西.北.中.发.白七种)和序数牌(分为条子.饼子.万子三种花色,每种花色各有一到九的九种牌),每种牌各四张.在 ...
- Highways poj 2485
Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public h ...
- AV 地址错误 map 文件 根据地址报错,查 Delphi 代码
1. 首先需要设置程序生成 map 文件.Project -> Options -> Linker -> Map file , Detailed 2. 计算公式Edit2.Text ...
- 【Linux】鸟哥的Linux私房菜基础学习篇整理(九)
1. quotacheck [-avugfM] [/mount_point]:扫描文件系统并创建Quota配置文件.参数:-a:扫描所有在/etc/mtab内,含有quota支持的文件系统,加上此参数 ...
- Apache Struts 多个开放重定向漏洞(CVE-2013-2248)
漏洞版本: Struts < 2.3.15.1 漏洞描述: BUGTRAQ ID: 61196 CVE(CAN) ID: CVE-2013-2248 Struts2 是第二代基于Model-Vi ...
- (转载)php flush()刷新不能输出缓冲的原因分析
(转载)http://www.webkaka.com/tutorial/php/2012/110628/ 在php程序编写中,flush()的使用率还是挺高的,它在网页表现即时信息效果时发挥了极为重要 ...