Android自定义控件
来源:互联网 发布:c语言韩信点兵点人数 编辑:程序博客网 时间:2024/06/05 20:42
概述
在现实生活中,如果我们要去画一个图形,必须先知道他的大小和位置,同样,在Android中,在绘制一个View前,也必须要先去测量将要绘制的View的大小,这个测量过程在onMeasure()方法中进行。
MeasureSpec类
Android系统给我们提供了一个强大的类MeasureSpec,通过这个类,可以帮助我们测量测量View,MeasureSpec是一个32位的int值,其中高2位代表测量的模式,低30位代表测量的大小。
所以说MeasureSpec类中包含View测量的模式和大小。
那么什么事测量的模式,什么是测量的大小呢?
测量的模式
测量有三种模式
EXACTLY (精确值模式): 当我们测量的控件的layout_width属性或者layout_height属性指定为具体的数值,比如
android:layout_width="200dp"
,或者指定为match_parent,比如android:layout_height="match_parent"
时,系统使用EXACTLY模式。AT_MOST(最大值模式):当我们测量的控件的layout_width属性或者layout_height属性指定为wrap_content时,即控件的大小一般随着其子空间或者内容的内容的变化而变化,此时控件的大小只要不超过父控件所允许的最大尺寸即可。
UNSPECIFIED (未指定模式):它未指定控件的大小测量模式,View想多大就多大,通常像ScrollView中这种类型控件使用这种模式。
onMeasure方法默认只支持EXACTLY模式,所以当我们自定义控件的时候,如果不去重写OnMeasure方法,就只能使用EXACTLY模式,控件可以响应你指定的具体的宽高值,或者match_parent属性。 如果你想要你的自定义View支持wrap_content属性,就必须要重写onMeasure()方法来制定wrap_content时的大小。
通过Meassure类,我们就获取了View的测量模式和View想要绘制的大小,有了这些信息,我们就可以控制View最后显示的大小。
实例讲解
我们写一个类继承View,重写它的onMeasure()方法
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
我们点击进入super.onMeasure()方法中,查看其源码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); }
可以发现其内部使用了setMeasuredDimension(int measuredWidth, int measuredHeight)方法将最终测量得到的宽高设置进去,从而完成测量的工作。所以,当我们在自定义控件时,通过重写onMeasure()方法,最终就是把测量后的结果作为参数设置给setMeasuredDimension(int measuredWidth, int measuredHeight)方法。
我们把自己定义控件的onMeasure方法进行重写:
//super.onMeasure(widthMeasureSpec, heightMeasureSpec); int measureWidthSize = measureWidth(widthMeasureSpec); int measureHeightSize = measureHeight(heightMeasureSpec); setMeasuredDimension(measureWidthSize, measureHeightSize); // 设置测量结果
private int measureWidth(int measureSpace) { // 获取测量模式 int mode = MeasureSpec.getMode(measureSpace); // 获取测量的大小 int size = MeasureSpec.getSize(measureSpace); if(mode == MeasureSpec.EXACTLY){ // 如果测量模式为精确测量,则直接返回测量的大小 return size; } else { int maxSize = 200; if(mode == MeasureSpec.AT_MOST){ // 如果是至多测量, return Math.min(maxSize, size); // 设置View的大小最大不能超过200 } } return 0; }
其中measureHeight()方法和measureWidth()方法内容一样。
现在我们在布局文件中设置这个使用这个自定义控件。
先给一个固定的值:
<com.itdujun.custom_view.CustomerView android:layout_width="400px" android:layout_height="400px" android:background="@color/colorAccent"/>
运行会查看结果:
然后在设置为match_parent:
<com.itdujun.custom_view.CustomerView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent"/>
设置为wrap_content
<com.itdujun.custom_view.CustomerView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/colorAccent"/>
因为我们在onMeasure()方法中,代码为如果测量模式为AT_MOST时,起最小尺寸为200px,所以这里显示200px的大小。
- [Android自定义控件] Android自定义控件
- Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- Android 自定义控件 单页翻书控件
- android虚线控件---自定义控件
- android自定义控件实例 --控件
- Android自定义控件--组合控件
- android 控件 自定义组合控件
- 【android自定义控件】ProgressBar自定义
- Android自定义控件 自定义属性
- Android自定义控件 -- 自定义View
- Android自定义控件 -- 自定义ViewGroup
- Android 自定义控件 自定义标题栏
- Android 自定义控件-自定义进度条。
- css中的盒子模型及其浮动
- PAT乙级 1025. 反转链表 (25)--结构体、容器vector、容器pair
- linux下安装svn
- linux学习之路——ubuntu 16.04 开机开启数字小键盘解决方法
- 为什么jdbctemplate是线程安全的
- Android自定义控件
- ROS学习(基于Ubuntu 15.04 和ROS Jade)第三章 ROS核心教程 之 9 使用rosed编辑ROS中的文件
- java8 自定义收集器Collector
- HDU 1321 棋盘问题
- VM12永久秘钥-激活码
- C++ Builder/ Dephi IDE 行显示插件CnWizards
- Quartz2D介绍
- 2017ChinaJoy展台曝光大比拼
- FPGA学习记录三