在自定义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方法时要根据模式不同进行尺寸计算。下面代码就是一种比较典型的方式:

[java] view plaincopy
  1. @Override
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  3. setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));
  4. }
  5. private int getMeasuredLength(int length, boolean isWidth) {
  6. int specMode = MeasureSpec.getMode(length);
  7. int specSize = MeasureSpec.getSize(length);
  8. int size;
  9. int padding = isWidth ? getPaddingLeft() + getPaddingRight()
  10. : getPaddingTop() + getPaddingBottom();
  11. if (specMode == MeasureSpec.EXACTLY) {
  12. size = specSize;
  13. } else {
  14. size = isWidth ? padding + mWave.length / 4 : DEFAULT_HEIGHT
  15. + padding;
  16. if (specMode == MeasureSpec.AT_MOST) {
  17. size = Math.min(size, specSize);
  18. }
  19. }
  20. return size;
  21. }

解决ScrollView嵌套ListView和GridView冲突的方法

[html] view plaincopy
  1. public class MyListView extends ListView {
  2. public MyListView(Context context) {
  3. super(context);
  4. }
  5. public MyListView(Context context, AttributeSet attrs) {
  6. super(context, attrs);
  7. }
  8. public MyListView(Context context, AttributeSet attrs, int defStyle) {
  9. super(context, attrs, defStyle);
  10. }
  11. @Override
  12. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  13. int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
  14. MeasureSpec.AT_MOST);
  15. super.onMeasure(widthMeasureSpec, expandSpec);
  16. }
  17. }
  18. public class MyGridView extends GridView {
  19. private boolean haveScrollbar = true;
  20. public MyGridView(Context context) {
  21. super(context);
  22. }
  23. public MyGridView(Context context, AttributeSet attrs) {
  24. super(context, attrs);
  25. }
  26. public MyGridView(Context context, AttributeSet attrs, int defStyle) {
  27. super(context, attrs, defStyle);
  28. }
  29. /**
  30. * 设置是否有ScrollBar,当要在ScollView中显示时,应当设置为false。 默认为 true
  31. *
  32. * @param haveScrollbars
  33. */
  34. public void setHaveScrollbar(boolean haveScrollbar) {
  35. this.haveScrollbar = haveScrollbar;
  36. }
  37. @Override
  38. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  39. if (haveScrollbars == false) {
  40. int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
  41. super.onMeasure(widthMeasureSpec, expandSpec);
  42. } else {
  43. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  44. }
  45. }
  46. }

来源: http://blog.csdn.net/yuhailong626/article/details/20639217
来自为知笔记(Wiz)

MeasureSpec学习相关推荐

  1. MeasureSpec学习 - 转

    2019独角兽企业重金招聘Python工程师标准>>> 在自定义View和ViewGroup的时候,我们经常会遇到int型的 MeasureSpec 来表示一个组件的大小,这个变量里 ...

  2. 那些年收藏的技术文章(一) CSDN篇

    #Android ##Android基础及相关机制 Android Context 上下文 你必须知道的一切 Android中子线程真的不能更新UI吗? Android基础和运行机制 Android任 ...

  3. 那些年收藏的技术文章(一)-CSDN篇

    Android Android基础及相关机制 Android View体系 Android坐标相关 Android事件机制及相关问题 Android官方组件 Android Service Andro ...

  4. 【学习】Android中View的工作原理(上)——ViewRoot、DecorView、MeasureSpec

    初识ViewRoot和DecorView ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot完成 ...

  5. Android开源中国客户端学习 (自定义View)左右滑动控件ScrollLayout

    左右滑动的控件我们使用的也是非常多了,但是基本上都是使用的viewpager 等 android基础的控件,那么我们有么有考虑过查看他的源码进行定制呢?当然,如果你自我感觉非常好的话可以自己定制一个, ...

  6. 红橙Darren视频笔记 流式布局tagLayout measure layout方法学习 adapter使用 学习感悟

    效果: 自定义View public class TagLayout extends ViewGroup {private static final String TAG = "TagLay ...

  7. android自定义View学习(二)----自定义绘图

    自定义绘图 自定义视图中最重要的部分是它的外观.根据您的应用需求,自定义绘图可以很容易或复杂.本篇涵盖了一些最常见的操作 onDraw() 绘制自定义视图中最重要的步骤是重写该onDraw()方法.参 ...

  8. 解决Android学习之ScollView嵌套ListView和GridView问题

    Android学习之ScollView嵌套ListView和GridView问题,gridview与这种写法一样 import android.content.Context; import andr ...

  9. Android学习之——ListView下拉刷新

    背景知识 ListView使用非常广泛,对于使用ListView的应用来说,下拉刷新是必不可少要实现的功能. 我们常用的微博.网易新闻,搜狐新闻都使用了这一功能,如下图所示.     微博 搜狐新闻 ...

最新文章

  1. 去除iphone图标的半弧高亮效果
  2. 评价一个软件的3个角度
  3. 关于5G技术和5G技术即将面临的各项挑战
  4. Android之数据转化崩溃问题
  5. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第5篇]复杂性类NP是什么意思?
  6. 漫画 | 面试的我 VS 真实的我
  7. sql相同顺序法和一次封锁法_不到75行代码,导出最高法指导案例到excel(一)...
  8. CodeVs 1017 乘积最大(DP)
  9. flex builder method
  10. Eclipse中好用的快捷键
  11. 日志分析里面的max是什么_mysql慢日志文件分析处理
  12. 2020 小米刷机相关总结
  13. [转]王垠的过去和现状
  14. Three.js凹凸贴图bumpMap和法线贴图.normalMap
  15. cad2012打开后闪退_windows7打不开CAD2012出现闪退的解决方法
  16. linux系统查询服务器型号,Linux系统查看服务器型号
  17. STM32F030软件SPI控制74HC165
  18. 计算机的应用与分类,办公自动化是计算机的一项应用,按计算机应用的分类,它属于(    )...
  19. VScode突然之间连接服务器显示不断重连retry多次
  20. 站在孙正义愿景基金背后的男人:他们才是软银科技版图的真正操盘手

热门文章

  1. python没有return语句的函数将返回_为什么Python没有return返回值
  2. php双线切换线路,双线路策略路由和脚本备份切换
  3. Fiddler软件基本配置教程
  4. CentOS7安装MySQL,全网最快安装教程
  5. jenkins组权限_Jenkins 中基于角色的权限管理
  6. Android5.1自定义闹钟铃声,Android 设置来电铃声、通知铃声、闹钟铃声中的坑
  7. Matrix(二维树状数组)入门第一题
  8. 一般判五年几年能出来_A股十年不涨的“元凶”被揪了出来,指数不该被冤枉...
  9. html设置设置字母间的距离,css如何设置字母间距?字母间距的设置方法
  10. DVR服务器如何装系统,车载监控dvr如何配置服务器