用服务器做网站空间,淮北论坛人才招聘网,王者荣耀网页设计报告,网站推广指标包括2019独角兽企业重金招聘Python工程师标准 在自定义View和ViewGroup的时候#xff0c;我们经常会遇到int型的 MeasureSpec 来表示一个组件的大小#xff0c;这个变量里面不仅有组件的尺寸大小#xff0c;还有大小的模式。 这个大小的模式#xff0c;有点难以理… 2019独角兽企业重金招聘Python工程师标准 在自定义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_width50dip或者为FILL_PARENT是都是控件大小已经确定的情况都是精确尺寸。 MeasureSpec.AT_MOST是最大尺寸当控件的layout_width或layout_height指定为WRAP_CONTENT时控件大小一般随着控件的子空间或内容进行变化此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此此时的mode是AT_MOSTsize给出了父控件允许的最大尺寸。 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);}Overrideprotected 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); } }
} 转载于:https://my.oschina.net/qiuhoude/blog/410809