【转】android中onMeasure初看,深入理解布局之一!
2013-11-19 17:59
369 查看
今天学习android自定义组件:docs/guide/topics/ui/custom-components.html
其中有两个对布局界面影响很的方法,onDraw(),和onMeasure().
onDraw()比较好理解.onMeasure()就比较难理解一些,也更复杂些,引用文档中的说法就是:
onMeasure()isalittlemoreinvolved.
其实还有另一个方面的原因就是我对这个单词measure不是很知道,然后果了下词典,就放了下心,确实是测量的意思.
实现onMeasure()方法基本需要完成下面三个方面的事情(最终结果是你自己写相应代码得出测量值并调用view的一个方法进行设置,告诉给你的view安排位置大小的父容器你要多大的空间.):
1.传递进来的参数,widthMeasureSpec,和heightMeasureSpec是你对你应该得出来的测量值的限制.
TheoveriddenonMeasure()methodiscalledwithwidthandheightmeasurespecifications(widthMeasureSpecandheightMeasureSpecparameters,bothareintegercodesrepresentingdimensions)whichshouldbetreatedasrequirementsfortherestrictionsonthewidth
andheightmeasurementsyoushouldproduce.
2.你在onMeasure计算出来设置的width和height将被用来渲染组件.应当尽量在传递进来的width和height声明之间.
虽然你也可以选择你设置的尺寸超过传递进来的声明.但是这样的话,父容器可以选择,如clipping,scrolling,或者抛出异常,或者(也许是用新的声明参数)再次调用onMeasure()
Yourcomponent'sonMeasure()methodshouldcalculateameasurementwidthandheightwhichwillberequiredtorenderthecomponent.itshouldtrytostaywithinthespecifiedpassedin.althoughitcanchoosetoexceedthem(inthiscase,theparentcanchoose
whattodo,includingclipping,scrolling,throwinganexcption,oraskingtheonMeasuretotryagain,perhapswithdifferentmeasurementspecifications).
3.一但width和height计算好了,就应该调用View.setMeasuredDimension(intwidth,intheight)方法,否则将导致抛出异常.
Oncethewidthandheightarecalculated,thesetMeasureDimension(intwidth,intheight)methodmustbecalledwiththecalculatedmeasurements.Failuretodothiswillresultinanexceptiionbeingthrown
在Android提提供的一个自定义View示例中(在APIdemos中的view/LabelView)可以看到一个重写onMeasure()方法的
实例,也比较好理解.
直接看measureWidth()
首先看到的是参数,分别代表宽度和高度的MeasureSpec
android2.2文档中对于MeasureSpec中的说明是:
一个MeasureSpec封装了从父容器传递给子容器的布局需求.
每一个MeasureSpec代表了一个宽度,或者高度的说明.
一个MeasureSpec是一个大小跟模式的组合值.一共有三种模式.
AMeasureSpecencapsulatesthelayoutrequirementspassedfromparenttochildEachMeasureSpecrepresentsarequirementforeitherthewidthortheheight.AMeasureSpeciscompsizedofasizeandamode.Therearethreepossiblemodes:
(1)UPSPECIFIED:父容器对于子容器没有任何限制,子容器想要多大就多大.
UNSPECIFIEDTheparenthasnotimposedanyconstraintonthechild.Itcanbewhateversizeitwants
(2)EXACTLY
父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.
EXACTLYTheparenthasdeterminedandexactsizeforthechild.Thechildisgoingtobegiventhoseboundsregardlessofhowbigitwantstobe.
(3)AT_MOST
子容器可以是声明大小内的任意大小.
AT_MOSTThechildcanbeaslargeasitwantsuptothespecifiedsize
MeasureSpec是View类下的静态公开类,MeasureSpec中的值作为一个整型是为了减少对象的分配开支.此类用于
将size和mode打包或者解包为一个整型.
MeasureSpecsareimplementedasintstoreduceobjectallocation.Thisclassisprovidedtopackandunpackthesize,modetupleintotheint
我比较好奇的是怎么样将两个值打包到一个int中,又如何解包.
MeasureSpec类代码如下:(注释已经被我删除了,因为在上面说明了.)
我无聊的将他们的十进制值打印出来了:
mode_shift=30,mode_mask=-1073741824,UNSPECIFIED=0,EXACTLY=1073741824,AT_MOST=-2147483648
然后觉得也应该将他们的二进制值打印出来,如下:
mode_shift=11110,//30
mode_mask=11000000000000000000000000000000,
UNSPECIFIED=0,
EXACTLY=1000000000000000000000000000000,
AT_MOST=10000000000000000000000000000000
对于上面的数值我们应该这样想,不要把0x3看成3而要看成二进制的11,
而把MODE_SHIFF就看成30.那为什么是二进制的11呢?
呢,因为只有三各模式,如果有四种模式就是111了因为111三个位才可以有四种组合对吧.
我们这样来看,
UNSPECIFIED=00000000000000000000000000000000,
EXACTLY=01000000000000000000000000000000,
AT_MOST=10000000000000000000000000000000
也就是说,0,1,2
对应00,01,10
当跟11想与时00&11还是得到00,11&01->01,10&
我觉得到了这个份上相信,看我博客的也都理解了.
return(measureSpec&~MODE_MASK);应该是return(measureSpec&(~MODE_MASK));
转自:/article/3475205.html
其中有两个对布局界面影响很的方法,onDraw(),和onMeasure().
onDraw()比较好理解.onMeasure()就比较难理解一些,也更复杂些,引用文档中的说法就是:
onMeasure()isalittlemoreinvolved.
其实还有另一个方面的原因就是我对这个单词measure不是很知道,然后果了下词典,就放了下心,确实是测量的意思.
实现onMeasure()方法基本需要完成下面三个方面的事情(最终结果是你自己写相应代码得出测量值并调用view的一个方法进行设置,告诉给你的view安排位置大小的父容器你要多大的空间.):
1.传递进来的参数,widthMeasureSpec,和heightMeasureSpec是你对你应该得出来的测量值的限制.
TheoveriddenonMeasure()methodiscalledwithwidthandheightmeasurespecifications(widthMeasureSpecandheightMeasureSpecparameters,bothareintegercodesrepresentingdimensions)whichshouldbetreatedasrequirementsfortherestrictionsonthewidth
andheightmeasurementsyoushouldproduce.
2.你在onMeasure计算出来设置的width和height将被用来渲染组件.应当尽量在传递进来的width和height声明之间.
虽然你也可以选择你设置的尺寸超过传递进来的声明.但是这样的话,父容器可以选择,如clipping,scrolling,或者抛出异常,或者(也许是用新的声明参数)再次调用onMeasure()
Yourcomponent'sonMeasure()methodshouldcalculateameasurementwidthandheightwhichwillberequiredtorenderthecomponent.itshouldtrytostaywithinthespecifiedpassedin.althoughitcanchoosetoexceedthem(inthiscase,theparentcanchoose
whattodo,includingclipping,scrolling,throwinganexcption,oraskingtheonMeasuretotryagain,perhapswithdifferentmeasurementspecifications).
3.一但width和height计算好了,就应该调用View.setMeasuredDimension(intwidth,intheight)方法,否则将导致抛出异常.
Oncethewidthandheightarecalculated,thesetMeasureDimension(intwidth,intheight)methodmustbecalledwiththecalculatedmeasurements.Failuretodothiswillresultinanexceptiionbeingthrown
在Android提提供的一个自定义View示例中(在APIdemos中的view/LabelView)可以看到一个重写onMeasure()方法的
实例,也比较好理解.
01 | /** |
02 | * |
03 | */ |
04 | @Override |
05 | protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) { |
06 | setMeasuredDimension(measureWidth(widthMeasureSpec), |
07 | measureHeight(heightMeasureSpec)); |
08 | } |
09 |
10 | /** |
11 | * |
12 | * |
13 | * |
14 | */ |
15 | private int measureWidth( int measureSpec) { |
16 | int result 0 ; |
17 | int specMode |
18 | int specSize |
19 |
20 | if (specMode |
21 | // |
22 | result |
23 | } else { |
24 | // |
25 | result int ) |
26 | + getPaddingRight(); |
27 | if (specMode |
28 | // |
29 | result |
30 | } |
31 | } |
32 |
33 | return result; |
34 | } |
首先看到的是参数,分别代表宽度和高度的MeasureSpec
android2.2文档中对于MeasureSpec中的说明是:
一个MeasureSpec封装了从父容器传递给子容器的布局需求.
每一个MeasureSpec代表了一个宽度,或者高度的说明.
一个MeasureSpec是一个大小跟模式的组合值.一共有三种模式.
AMeasureSpecencapsulatesthelayoutrequirementspassedfromparenttochildEachMeasureSpecrepresentsarequirementforeitherthewidthortheheight.AMeasureSpeciscompsizedofasizeandamode.Therearethreepossiblemodes:
(1)UPSPECIFIED:父容器对于子容器没有任何限制,子容器想要多大就多大.
UNSPECIFIEDTheparenthasnotimposedanyconstraintonthechild.Itcanbewhateversizeitwants
(2)EXACTLY
父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.
EXACTLYTheparenthasdeterminedandexactsizeforthechild.Thechildisgoingtobegiventhoseboundsregardlessofhowbigitwantstobe.
(3)AT_MOST
子容器可以是声明大小内的任意大小.
AT_MOSTThechildcanbeaslargeasitwantsuptothespecifiedsize
MeasureSpec是View类下的静态公开类,MeasureSpec中的值作为一个整型是为了减少对象的分配开支.此类用于
将size和mode打包或者解包为一个整型.
MeasureSpecsareimplementedasintstoreduceobjectallocation.Thisclassisprovidedtopackandunpackthesize,modetupleintotheint
我比较好奇的是怎么样将两个值打包到一个int中,又如何解包.
MeasureSpec类代码如下:(注释已经被我删除了,因为在上面说明了.)
01 | public static class MeasureSpec { |
02 | private static final int MODE_SHIFT 30 ; |
03 | private static final int MODE_MASK 0x3 << MODE_SHIFT; |
04 |
05 | public static final int UNSPECIFIED 0 << MODE_SHIFT; |
06 | public static final int EXACTLY 1 << MODE_SHIFT; |
07 | public static final int AT_MOST 2 << MODE_SHIFT; |
08 |
09 | public static int makeMeasureSpec( int size, int mode) { |
10 | return size |
11 | } |
12 | public static int getMode( int measureSpec) { |
13 | return (measureSpec |
14 | } |
15 | public static int getSize( int measureSpec) { |
16 | return (measureSpec |
17 | } } |
mode_shift=30,mode_mask=-1073741824,UNSPECIFIED=0,EXACTLY=1073741824,AT_MOST=-2147483648
然后觉得也应该将他们的二进制值打印出来,如下:
mode_shift=11110,//30
mode_mask=11000000000000000000000000000000,
UNSPECIFIED=0,
EXACTLY=1000000000000000000000000000000,
AT_MOST=10000000000000000000000000000000
1 | MODE_MASK 0x3 << //也就是说MODE_MASK是由11左移30位得到的.因为Java用补码表示数值.最后得到的值最高位是1所以就是负数了 |
1 |
而把MODE_SHIFF就看成30.那为什么是二进制的11呢?
呢,因为只有三各模式,如果有四种模式就是111了因为111三个位才可以有四种组合对吧.
我们这样来看,
UNSPECIFIED=00000000000000000000000000000000,
EXACTLY=01000000000000000000000000000000,
AT_MOST=10000000000000000000000000000000
也就是说,0,1,2
对应00,01,10
当跟11想与时00&11还是得到00,11&01->01,10&
我觉得到了这个份上相信,看我博客的也都理解了.
return(measureSpec&~MODE_MASK);应该是return(measureSpec&(~MODE_MASK));
转自:
相关文章推荐
- android中onMeasure初看,深入理解布局之一!
- android中onMeasure初看,深入理解布局之一!
- android中onMeasure初看,深入理解布局之一!
- 【view】android中onMeasure初看,深入理解布局之一!
- Android 自定义View实现圆形进度条 深入理解onDraw和onMeasure及自定义属性
- Android流式布局FlowLayout的实现,Android布局的内部机制onMeasure、onLayout
- Android自定义View(三、深入解析控件测量onMeasure)
- Android View.onMeasure方法的理解
- Android onMeasure,onLayout,onDraw的理解
- Android下如何理解onMeasure,onLayout的过程
- [置顶] Android自定义View(三、深入解析控件测量onMeasure)
- Android View.onMeasure方法的理解
- [转载]Android View.onMeasure方法的理解
- Android View.onMeasure方法的理解
- android 自定义view中onMeasure()理解
- Android中对于onMeasure()的理解
- Android View.onMeasure方法的理解
- Android View.onMeasure方法的理解
- 快速理解android View的测量onMeasure()与MeasureSpec
- Android View.onMeasure方法的理解