android自定义View探索3(onMeasure深入分析一)
2017-06-15 16:27
483 查看
前言:
从去年7月到北方马上一年了,一年的外包生活有喜有泪,喜的是技术提升很快,为人成熟了,在上海时总认为自己是小孩子;泪的话远离家乡,没有家人,朋友不多。但是总归在进步,不习惯也会习惯。哈哈加油吧。
在上篇文章android自定义View探索2我们已经看到了,XML使用我们自定义View的时候直接设置wrap_content无效。
为什么无效?
因为我们没有对自定义View设置大小,而绘制到屏幕中的View必须指定具体的大小,没有指定大小就像上篇文章中演示的默认是MatchParent,一般情况下这很能满足我们
需求,这时候就要用到onMeasure.
先来看看onMeasure的源码
以上是View.class中自定义View的源码,android中每一个控件都会重写它,有兴趣可以去看看。
我们看到它有两个参数widthMeasureSpec、heightMeasureSpec,那么这两个参数用来干吗的呢?
这两个值分别用于确定视图的宽度和高度的规格和大小,什么宽度和规格和高度和大小,怎么包含这么多信息呢?对,你没有看错,那么一个int怎么可以存放这么多信息的
呢?下面我们来深入分析MeasureSpec。
任玉刚的《Android开发探索》是这么说的:
“确切来说,MeasureSpec在很大程度上决定了一个View控件的尺寸规格。”
很大程度上难道还有其他因素?除了自身因素外他还受父容器的影响。那么父容器是怎么影响View控件的尺寸规格的呢?
在测量的过程中,系统会将View的LayoutParams跟据父容器所施加的规则转换成对应的MeasureSpec,所以MeasureSpec是受到父容器影响的,还有宽高是测量的宽高,
不一定等于最终的宽高。
前面我们提到过一个问题,MeasureSpec怎么包含这么多信息呢?
MeasureSpec是一个32位的int值,它由specMode和SpecSize组成;其中高2位代表SpecMode,低30位代表SpecSize。那么SpecMode和SpecSize分别代表了什么呢?为
什么把SpecMode和SpecSize打包到一起呢?
先来回答第一个问题,SpecMode和SpecSize分别用来干什么的?
SpecMode:测量模式。
SpecSize:在某种测量模式下的规格大小
第一个问题解决了再来看看第二个问题,为什么把SpecMode和SpecSize打包到一起呢?
解决这个文题前先来看看源码:
View.class
来看看三个方法的功能吧:
1.makeMeasureSpec方法:这个方法通过将SpecMode和SpecSize打包成一个int值。从中我们也可以发现,把SpecMode和SpecSize打包成一个int值是为
了避免过多的对象内存分配。
2.getMode方法:这个方法把SpecMode解包了。
3.getSize方法:这个方法把SpecSize解包了。
从以上代码中我们可以看出SpecMode的取值模式有三种:
UNSPECIFIED.
这种模式下开发人员可以将View设置成任意大小,没有任何限制,不过这种模式在开发中用的比较少。
EXACTLY:
这种模式下View的最终大下就是SpecSize所指定的值,它对应的大小可以是LayoutParams的MatchParent或具体的值。我们在上篇文章中wrap_content全屏默认就是这种模式。
AT_MOST:
表示View的大小不能超过SpecSize,当然开发者也可以自己设置大小。
从去年7月到北方马上一年了,一年的外包生活有喜有泪,喜的是技术提升很快,为人成熟了,在上海时总认为自己是小孩子;泪的话远离家乡,没有家人,朋友不多。但是总归在进步,不习惯也会习惯。哈哈加油吧。
一 onMeasure简介
onMeasure是用来干嘛的?measure是测量的意思,从字面上我们就可以知道它是用来测量视图的宽高尺寸的。问题来了为什么要在onMeasure()里测量尺寸呢?在上篇文章android自定义View探索2我们已经看到了,XML使用我们自定义View的时候直接设置wrap_content无效。
为什么无效?
因为我们没有对自定义View设置大小,而绘制到屏幕中的View必须指定具体的大小,没有指定大小就像上篇文章中演示的默认是MatchParent,一般情况下这很能满足我们
需求,这时候就要用到onMeasure.
先来看看onMeasure的源码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); }
以上是View.class中自定义View的源码,android中每一个控件都会重写它,有兴趣可以去看看。
我们看到它有两个参数widthMeasureSpec、heightMeasureSpec,那么这两个参数用来干吗的呢?
这两个值分别用于确定视图的宽度和高度的规格和大小,什么宽度和规格和高度和大小,怎么包含这么多信息呢?对,你没有看错,那么一个int怎么可以存放这么多信息的
呢?下面我们来深入分析MeasureSpec。
二 MeasureSpec详解
MeasureSpec是干什么用的?任玉刚的《Android开发探索》是这么说的:
“确切来说,MeasureSpec在很大程度上决定了一个View控件的尺寸规格。”
很大程度上难道还有其他因素?除了自身因素外他还受父容器的影响。那么父容器是怎么影响View控件的尺寸规格的呢?
在测量的过程中,系统会将View的LayoutParams跟据父容器所施加的规则转换成对应的MeasureSpec,所以MeasureSpec是受到父容器影响的,还有宽高是测量的宽高,
不一定等于最终的宽高。
前面我们提到过一个问题,MeasureSpec怎么包含这么多信息呢?
MeasureSpec是一个32位的int值,它由specMode和SpecSize组成;其中高2位代表SpecMode,低30位代表SpecSize。那么SpecMode和SpecSize分别代表了什么呢?为
什么把SpecMode和SpecSize打包到一起呢?
先来回答第一个问题,SpecMode和SpecSize分别用来干什么的?
SpecMode:测量模式。
SpecSize:在某种测量模式下的规格大小
第一个问题解决了再来看看第二个问题,为什么把SpecMode和SpecSize打包到一起呢?
解决这个文题前先来看看源码:
View.class
private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT; public static final int UNSPECIFIED = 0 << MODE_SHIFT; public static final int EXACTLY = 1 << MODE_SHIFT; public static final int AT_MOST = 2 << MODE_SHIFT; public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size, @MeasureSpecMode int mode) { if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { return (size & ~MODE_MASK) | (mode & MODE_MASK); } } public static int getMode(int measureSpec) { //noinspection ResourceType return (measureSpec & MODE_MASK); } public static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK); }
来看看三个方法的功能吧:
1.makeMeasureSpec方法:这个方法通过将SpecMode和SpecSize打包成一个int值。从中我们也可以发现,把SpecMode和SpecSize打包成一个int值是为
了避免过多的对象内存分配。
2.getMode方法:这个方法把SpecMode解包了。
3.getSize方法:这个方法把SpecSize解包了。
从以上代码中我们可以看出SpecMode的取值模式有三种:
UNSPECIFIED.
这种模式下开发人员可以将View设置成任意大小,没有任何限制,不过这种模式在开发中用的比较少。
EXACTLY:
这种模式下View的最终大下就是SpecSize所指定的值,它对应的大小可以是LayoutParams的MatchParent或具体的值。我们在上篇文章中wrap_content全屏默认就是这种模式。
AT_MOST:
表示View的大小不能超过SpecSize,当然开发者也可以自己设置大小。
相关文章推荐
- android自定义View探索5(onMeasure深入分析二LayoutParams)
- (转)Android自定义View(三、深入解析控件测量onMeasure)
- Android自定义View(三、深入解析控件测量onMeasure)
- Android 自定义View实现圆形进度条 深入理解onDraw和onMeasure及自定义属性
- Android自定义View(三、深入解析控件测量onMeasure)
- [置顶] Android自定义View(三、深入解析控件测量onMeasure)
- Android自定义View(三、深入解析控件测量onMeasure)
- Android自定义View-onMeasure介绍
- Android中View的绘制过程 onMeasure方法简述 附有自定义View例子
- android 自定义view中onMeasure()理解
- Android 自定义 View 之 onLayout 源码分析
- Android中View的绘制过程 onMeasure方法简述 附有自定义View例子
- Android 自定义 view(四)—— onMeasure 方法理解
- Android之自定义View,你需要了解和掌握的onMeasure测量规则
- Android中View的绘制过程 onMeasure方法简述 附有自定义View例子
- Android 自定义View 测量控件大小onMeasure中MeasureSpec作用
- Android学习自定义View(五)——自定义ViewGroup及其onMeasure()的理解
- Android 自定义 view(四)—— onMeasure 方法理解
- Android自定义ViewGroup:onMeasure与onLayout(1)
- Android 自定义View 中的OnMeasure的用法