原文地址:http://blog.csdn.net/yuhailong626/article/details/20639217
 
在自定义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方法时要根据模式不同进行尺寸计算。下面代码就是一种比较典型的方式:

  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冲突的方法

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

Android——MeasureSpec学习 - 解决ScrollView嵌套ListView和GridView冲突的方法的更多相关文章

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

    本文摘抄自:http://blog.csdn.net/yuhailong626/article/details/20639217 原文地址:http://blog.csdn.net/yuhailong ...

  2. Android之ScrollView嵌套ListView和GridView冲突

    由于ListView,GridView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView, 在ScrollView中嵌套使用ListView或者GridView,L ...

  3. (转)解决ScrollView嵌套ListView或者GridView导致只显示一行的方法

    即动态获取ListView和GridView的高度 一.对于ListView ListView listview= new ListView(this); setListViewHeightBased ...

  4. android中ScrollView嵌套ListView或GridView显示位置问题

    Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...

  5. 一键解决ScrollView嵌套ListView仅仅显示一行的问题

    /** * 解决ScrollView嵌套ListView仅仅显示一行的问题 * * @param listView */ private void setListViewHeightBasedOnCh ...

  6. android 解决ScrollView嵌套ListView的问题,不能全屏,全屏不能显示下面控件

    在开发中遇到ScrollView嵌套ListView的问题,最开始发出不能全屏,效果是这样的: 但我想要的效果是这样的: 下面看一下布局文件: <?xml version="1.0&q ...

  7. 转:四种方案解决ScrollView嵌套ListView问题

    转载自:http://blog.sina.com.cn/s/blog_46798aa80101lxbk.html 原始的连接已经不知道是哪里了,项目中遇到了同样的问题,花了一下午都没有想到是嵌套引起的 ...

  8. 转-四种方案解决ScrollView嵌套ListView问题

    本人网上用的ID是泡面或安卓泡面,学习一年半之前开始从事Android应用开发,这是我写的第一篇Android技术文章,转载请注明出处和作者,有写的不好的地方还请帮忙指出,谢谢. 在工作中,曾多次碰到 ...

  9. 四种方案解决ScrollView嵌套ListView问题(转)

    以下文章转自@安卓泡面 在工作中,曾多次碰到ScrollView嵌套ListView的问题,网上的解决方法有很多种,但是杂而不全.我试过很多种方法,它们各有利弊. 在这里我将会从使用ScrollVie ...

随机推荐

  1. 关于Java读取mysql中date类型字段默认值'0000-00-00'的问题

    今天在做项目过程中,查询一个表中数据时总碰到这个问题:      java.sql.SQLException:Value '0000-00-00' can not be represented as ...

  2. SharePoint下在Feature中动态Register/Remove HttpModule

    在SharePoint开发时,你会遇到这样一个问题,Global.asax去哪儿?怎样添加一个Global.asax?怎样在Application_Start这个事件处理程序里设置初始化?似乎在Vis ...

  3. pyspark RandomForestRegressor 随机森林回归

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Fri Jun 8 09:27:08 2018 ...

  4. java web项目中打开资源文件中文乱码

    1 java web项目中经常使用多模块管理.在某一个模块中添加了一些资源文件.但不是启动项目.有时候需要在程序中读取资源文件内容,打包后放到容器中就不能正常运行了.需要将所有资源文件放到启动项目的 ...

  5. javascript 20个正则表达式

    正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑.熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升. 正则表达式经常被用于 ...

  6. ssm redis 数据字典在J2EE中的多种应用与实现

    数据字典在项目中是不可缺少的“基础设施”,关于数据字典如何设计如何实现,今天抽空讲一下吧 先看一下表设计: 通过自定义标签来实现页面的渲染: public class DataDictValueTag ...

  7. Golang之字符串格式化

    字符串格式化 // Go 之 字符串格式化 // // Copyright (c) 2015 - Batu // package main import ( "fmt" ) typ ...

  8. WCF学习分享2

    整个solution结构例如以下: 以下介绍每一个project: 1. Service.Interface 定义契约 ICalculator.cs watermark/2/text/aHR0cDov ...

  9. HTML5学习笔记(十七):访问器和class关键字

    访问器 在ECMAScript5中,提供了Object.defineProperty的方法,我们可以通过该方法来控制属性的更多权限. 属性类型 我们先看一段定义属性的代码: var person = ...

  10. mongoose查询不到数据表中的数据的问题

    在做分类管理的时候,在数据库中创建了一张category表,但使用下面这行代码始终查不到表里的数据,也没有任何报错. var Category = mongoose.model('Category', ...