android View的测量问题
来源:互联网 发布:profili软件 编辑:程序博客网 时间:2024/05/18 03:12
转载自:http://www.cnblogs.com/manuosex/p/5280151.html
对于Android View的测量,我们一句话总结为:”给我位置和大小,我就知道您长到那里”。
为了让大家更好的理解这个结论,我这里先讲一个日常生活中的小故事:不知道大家玩过”瞎子画画”的游戏没,一个人蒙上眼睛,拿笔去画板上画一些指定的图案,另外一个人则充当他的”眼睛”,通过语言告诉他在画板那个位置画一个多大的图案。倘若,这个人不告诉那个蒙着眼睛的人,在那个画一个多大的图案。那么这个蒙着眼睛的人此时真是”河里赶大车———-没辙”。其实,Android就是这个蒙着眼睛的人,我们必须精确地告诉他如何去画,它才能画出你所想要的图形。
大家是不是对Android布局的测量进行现实世界进行类比了。为了实现View具体布局在哪儿,Android设计了一个短小精悍又功能强大的类——measureSpec类。这样妈妈再也不用担心我不会测量View了。那么,MeasureSpec到底是个什么鬼了。MeasureSpec,归根结底是一个32位的int值。其中高2位表示测量的模式,低30位表示测量View的大小。这样做有什么好处。这样做通过位运算来提高运行效率。
要了解MeasureSpec这个类的来弄去脉的话,务必要对测量的三种模式了解。
1.EXACTLY(精准的)
当您设置View的layout_height属性或layout_width属性为确定的值或者为match_parent(填充父容器)时候,系统就将View测量模式设置为EXACTLY模式。
2.AT_MOST(最大值)
即布局为最大值模式,那么什么时候系统会将View调整为AT_MOST模式了,即当您设置View的layout_height属性或layout_width属性为wrap_content(包裹内容)时候。
3.UNSPECIFIED(未确定)
即没有确定,没有指定大小测量模式,view即“心有多大,舞台就有多大”。这个方法,一般在自定义控件中才能用到。
View测量的时候,默认是EXACTLY模式,也许你会感到纳闷,TextView,EditText这些控件,他怎么就支持wrap_content属性了,难道他重写OnMeasure方法,是的,他们都重写OnMeasure方法。这就是为什么我们在自定义控件的时候,如果要布局支持wrap_content属性,就需要重写onMeasure方法,来指定wrap_content为确切的大小。
这个关于测量模式的思维导图应该是这样的:
我们知道这么多理论的知识,是不是觉得即枯燥乏味又觉得然并卵。好吧,我们就直接上代码,在代码中解释MeasureSpec如何获取测量模式和测量的大小。源代码如下:
Java代码如下:public class MyView extends View { public MyView(Context context, AttributeSet attrs) { super(context, attrs); }} xml代码如下:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <com.example.test.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00ff00" /></LinearLayout>
运行效果如下所示:
通过这个短小精悍的例子,充分证明这样一个结论:View测量的时候,默认是EXACTLY模式,你不重写OnMeasure方法,即使设置wrap_content属性,他也是填充父容器。
那么,就通过MeasureSpec这个万金油类来重写一下OnMeasure方法。相应源代码如下:
public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureWidth(heightMeasureSpec)); } public int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = 200; if (specMode == MeasureSpec.AT_MOST) { result = Math.min(specSize, result); } } return result; }
运行效果如下:
同样的例子,我们只不过是重写了OnMeasure方法,通过MeasureSpec.getMode(measureSpec)获取测量模式的时候,通过MeasureSpec.getSize(measureSpec)获取控件尺寸。判断当布局属性为wrap_content,指定为一确切值,这时,控件就符合wrap_content属性。
文章是比较短,不过是个细节问题,很多时候自定义View的时候没去关注这个东西,虽然一般可能不会遇到这个问题,遇到了的画,可以有个解决方式
- android View的测量问题
- Android View的测量
- Android View的测量
- Android View的测量
- 带着问题学习Android中View的measure测量
- Android View的测量过程
- android view 的测量过程
- View的测量(Android群英传)
- Android之View的测量
- android view的测量模式
- (转)Android View的测量
- Android自定义View(一) View的测量
- Android自定义View 之 View的测量
- Android 自定义View基础-View的测量
- Android之View的视图测量过程
- android中view的宽高测量
- Android:View的测量/onMeasure()方法解析
- 《Android 群英传》读书笔记: View 的测量
- 【LeetCode】
- 怎样理解阻塞非阻塞与同步异步的区别
- 使用带参数构造函数继承时注意
- iOS面试总结(一)
- 数据库连接池
- android View的测量问题
- iOS7以后NavigationBar下的UIScrollView
- 条件高斯分布
- CentOS7.1 KVM虚拟化之虚拟机内存、CPU调整(6)
- C语言冒泡排序
- JVM:内存结构和相关参数
- 安装scrapy时遇到的问题
- ubantu 常见问题
- 第一回:优秀的产品经理需要具备哪些能力——老吴说产品