Android 自定义View基础-View的测量
来源:互联网 发布:手机移动网络如何改dns 编辑:程序博客网 时间:2024/05/01 18:45
Android系统在绘制View前,必须对View进行测量,也就是告诉系统你要绘制多大的View,这个过程在onMeasure()方法中进行。Android系统提供一个类——MeasureSpec类,通过它来帮助我们测量View,MeasureSpec是一个32位int值,其中高两位为测量的模式,低30位为测量的大小。测量模式分为以下三种:(1)EXACTLY 即精确值模式。当我们将控件的layout_width属性或layout_height属性指定为具体数值时,比如android:layout_width="50dp",或者指定为match_parent属性时,系统使用的是EXACTLY模式。(2)AT_MOST 即最大值模式,当控件的layout_width属性或layout_height属性指定为wrap_content时,控件大小一般随着控件的子控件或内容的变化而变化。这时控件的尺寸只要不超过父控件允许的最大尺寸即可。(3)UNSPECIFIED 这个属性不指定大小测量模式,View想多大就多大,通常情况下载绘制自定义View时才会使用。 View类默认的onMeasure()方法只支持EXACTLY模式,所以如果再自定义控件的时候不重写onMeasure()方法的话,就只能使用EXACTLY模式。控件可以响应你指定的具体宽高值或者是match_parent属性。如果要让自定义View支持wrap_content属性,那么就必须重写onMeasure()方法来指定wrap_content时的大小。 我们可以通过MeasureSpec这个类来获取View的测量模式和View想要绘制的大小。有了这些信息,我们就可以控制View最后显示的大小。 首先我们来看onMeasure方法:
@Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){ super.onMeasure(widthMeasureSpec,heightMeasureSpec); }
通过查看super.onMeasure()方法,可以发现,系统最终会调用setMeasuredDimension(int measuredWidth, int measuredHeight)方法将测量后的宽高值设置进去,从而完成测量的工作。所以在重写onMeasure()方法后,最终的工作就是要把测量后的宽高值作为参数设置给setMeasuredDimension()方法。通过上面的分析,重写的onMeasure()方法代码如下所示:
@Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){ setMeasuredDimension( measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); }
在onMeasure()方法中,我们调用自定义的measureWidth()方法和measureHeight()方法,分别对宽高进行重新定义,参数则是宽和高的MeasureSpec对象,MeasureSpec对象中包含了测量的模式和测量值的大小。以measureWidth()为例,讲解如何自定义测量值:第一步,从MeasureSpec对象中提取出具体的测量模式和大小,代码如下所示:
int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);
接下来通过判断测量的模式,给出不同的测量值。当specMode为EXACTLY时,直接使用指定的specSize值;当specMode为其他两种模式时,需要给它一个默认的大小。特别地,如果指定wrap_content属性,即AT_MOST模式,则需要取出我们指定的大小与specSize中最小的一个来作为最后的测量值(因为wrap_content属性就是能包含内容的最小宽高),measureWidth()方法的代码如下所示,这段代码基本上可以作为模板代码:
private int measureWidth(int measureSpec){ int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if(specMode == MeasureSpec.EXACTLY){ resule = specSize; }else{ result = 100; if(specMode == MeasureSpec.AT_MOST){ result = Math.min(result,specSize); } } return result; }
measureHeight()方法与measureWidth()基本一致。这样我们就完成了View的测量。Tips:当指定宽高属性为wrap_content属性时,如果不重写onMeasure()方法,那么系统就不知道该使用默认多大的尺寸。因此,它就会默认填充整个父布局,所以重写onMeasure()方法的目的,就是为了能够给View一个wrap_content属性下的默认大小。
0 0
- Android 自定义View基础-View的测量
- Android自定义View(一) View的测量
- Android自定义View 之 View的测量
- 自定义View的测量
- android 自定义View之View的测量(onMeasure()方法)
- (转)Android自定义View 之 View的测量
- android 自定义View之View的测量(onMeasure()方法)
- Android View的测量
- Android View的测量
- Android View的测量
- 探究自定义View的测量
- Android 自定义View基础-View的绘制
- Android View的测量过程
- android View的测量问题
- android view 的测量过程
- View的测量(Android群英传)
- Android之View的测量
- android view的测量模式
- Linux vim保存只读文件
- restframework之Class-View-Based
- 我的c学习: 字符数据
- sql表,库的创建和删除
- web页面刷新
- Android 自定义View基础-View的测量
- React Native技术周报一
- Git和SVN的区别
- Linux安装软件 X64 变换版本 X86
- docker 的LXC技术
- 几种范数的简单介绍
- 存储引擎 MyISAM 和 InnoDB 的区别
- Linux学习之系统定时任务
- String、StringBuffer类