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学习相关推荐
- MeasureSpec学习 - 转
2019独角兽企业重金招聘Python工程师标准>>> 在自定义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的应用来说,下拉刷新是必不可少要实现的功能. 我们常用的微博.网易新闻,搜狐新闻都使用了这一功能,如下图所示. 微博 搜狐新闻 ...
最新文章
- 去除iphone图标的半弧高亮效果
- 评价一个软件的3个角度
- 关于5G技术和5G技术即将面临的各项挑战
- Android之数据转化崩溃问题
- [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第5篇]复杂性类NP是什么意思?
- 漫画 | 面试的我 VS 真实的我
- sql相同顺序法和一次封锁法_不到75行代码,导出最高法指导案例到excel(一)...
- CodeVs 1017 乘积最大(DP)
- flex builder method
- Eclipse中好用的快捷键
- 日志分析里面的max是什么_mysql慢日志文件分析处理
- 2020 小米刷机相关总结
- [转]王垠的过去和现状
- Three.js凹凸贴图bumpMap和法线贴图.normalMap
- cad2012打开后闪退_windows7打不开CAD2012出现闪退的解决方法
- linux系统查询服务器型号,Linux系统查看服务器型号
- STM32F030软件SPI控制74HC165
- 计算机的应用与分类,办公自动化是计算机的一项应用,按计算机应用的分类,它属于( )...
- VScode突然之间连接服务器显示不断重连retry多次
- 站在孙正义愿景基金背后的男人:他们才是软银科技版图的真正操盘手
热门文章
- python没有return语句的函数将返回_为什么Python没有return返回值
- php双线切换线路,双线路策略路由和脚本备份切换
- Fiddler软件基本配置教程
- CentOS7安装MySQL,全网最快安装教程
- jenkins组权限_Jenkins 中基于角色的权限管理
- Android5.1自定义闹钟铃声,Android 设置来电铃声、通知铃声、闹钟铃声中的坑
- Matrix(二维树状数组)入门第一题
- 一般判五年几年能出来_A股十年不涨的“元凶”被揪了出来,指数不该被冤枉...
- html设置设置字母间的距离,css如何设置字母间距?字母间距的设置方法
- DVR服务器如何装系统,车载监控dvr如何配置服务器