MeasureSpec学习 - 转
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_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);}@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
MeasureSpec学习 - 转相关推荐
- MeasureSpec学习
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式. 这个大小的模式,有点难以理解.在系统 ...
- 那些年收藏的技术文章(一) CSDN篇
#Android ##Android基础及相关机制 Android Context 上下文 你必须知道的一切 Android中子线程真的不能更新UI吗? Android基础和运行机制 Android任 ...
- 那些年收藏的技术文章(一)-CSDN篇
Android Android基础及相关机制 Android View体系 Android坐标相关 Android事件机制及相关问题 Android官方组件 Android Service Andro ...
- 【学习】Android中View的工作原理(上)——ViewRoot、DecorView、MeasureSpec
初识ViewRoot和DecorView ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot完成 ...
- Android开源中国客户端学习 (自定义View)左右滑动控件ScrollLayout
左右滑动的控件我们使用的也是非常多了,但是基本上都是使用的viewpager 等 android基础的控件,那么我们有么有考虑过查看他的源码进行定制呢?当然,如果你自我感觉非常好的话可以自己定制一个, ...
- 红橙Darren视频笔记 流式布局tagLayout measure layout方法学习 adapter使用 学习感悟
效果: 自定义View public class TagLayout extends ViewGroup {private static final String TAG = "TagLay ...
- android自定义View学习(二)----自定义绘图
自定义绘图 自定义视图中最重要的部分是它的外观.根据您的应用需求,自定义绘图可以很容易或复杂.本篇涵盖了一些最常见的操作 onDraw() 绘制自定义视图中最重要的步骤是重写该onDraw()方法.参 ...
- 解决Android学习之ScollView嵌套ListView和GridView问题
Android学习之ScollView嵌套ListView和GridView问题,gridview与这种写法一样 import android.content.Context; import andr ...
- Android学习之——ListView下拉刷新
背景知识 ListView使用非常广泛,对于使用ListView的应用来说,下拉刷新是必不可少要实现的功能. 我们常用的微博.网易新闻,搜狐新闻都使用了这一功能,如下图所示. 微博 搜狐新闻 ...
最新文章
- LetCode 70. Climbing Stairs--动态规划-爬梯子--递归等解法
- 关于事件相关电位SSVEP应用于视频游戏的研究
- VS2013常用快捷方式
- aop简介-aop相关概念
- sort和qsort函数的用法
- (61)FPGA译码器实现(function)
- Ubuntu 系统进不去 左上角减号
- 数据分析融入至BI工具的新思路
- thymeleaf判断对象是否为空的相关逻辑处理
- CryptoJS与C#AES加解密互转
- 国外设计素材网址干货
- 实变函数(4)--Lebesgue积分
- Self-assessment Checklists of HSK
- Ubuntu 20.04 离线安装podman
- NVIDIA GeForce RTX 3080 with CUDA capability sm_86 is not compatible with the current PyTorch
- 用计算机丧失了大脑,《心理科》您真的需要大脑“升级”吗? 将大脑视为计算机是有缺...
- 江民KV2008离线包和安装包下载 2007-12-24
- 绝地求生——PUBG吃鸡游戏模糊,画质很差
- ConViT:使用软卷积归纳偏置改进视觉变换器
- linux中exp命令详解_exp/imp命令的介绍和使用