View的测量
来源:互联网 发布:python exit(1) 编辑:程序博客网 时间:2024/05/18 03:47
在现实生活中,如果我们要去画一个图形,就必须知道它的大小和位置。同样,Android系统在绘制View之前,也必须对View进行测量,即告诉系统该画一个多大的View。这个过程在onMeasure()方法中进行。
Android系统给我们提供了一个设计短小精悍却功能强大的类--MeasureSpec类,通过它来帮助我们测量View。MeasureSpec是一个32位的int值,其中高2位为测量模式,低30位为测量的大小,在计算中使用位运算是为了提高效率。
测量的模式可以为以下三种:
- EXACTLY
即精准值模式,当我们将控件的layout_with属性或layout_height属性指定为具体数值时,比如100dp,或制定为match_parent,系统使用的是EXACTLY模式。
- AT_MOST
即最大值模式,当我们将控件的layout_with属性或layout_height属性指定为wrap_content时,控件大小一般随着控件的子控件或内容的变化而变化,此时控件的尺寸只要不超过父控件允许的最大尺寸即可。
- UNSPECIFIED
这个属性比较奇怪---它不知道其大小测量模式,View想多大就多大,通常情况下绘制自定义View时才会使用。
View类默认的onMeasure()方法只支持EXACTLY模式,所以如果在自定义控件的时候不重写onMeasure()方法的话,就只能使用EXACTLY模式。控件可以响应你指定的具体宽高值或者是match_parent属性。而如果要让自定义控件支持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()方法将测量后的宽高度设置进去,从而完成测量工作。所以再重写onMeasure()方法后,最终要做的工作就是把测量后的宽高度值作为参数设置给setMeasuredDimension()方法。
下面时测试的例子:
public class MyTextView extends android.support.v7.widget.AppCompatTextView { public MyTextView(Context context) { super(context); } public MyTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureWidth(int widthMeasureSpec){ int result = 0; int mode = MeasureSpec.getMode(widthMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); if(mode == MeasureSpec.EXACTLY){ result = size; } else { result = 200; if(mode == MeasureSpec.AT_MOST){ result = Math.min(result, size); } } return result; } private int measureHeight(int heightMeasureSpec){ int result = 0; int mode = MeasureSpec.getMode(heightMeasureSpec); int size = MeasureSpec.getSize(heightMeasureSpec); if(mode == MeasureSpec.EXACTLY){ result = size; } else { result = 200; if(mode == MeasureSpec.AT_MOST){ result = Math.min(result, size); } } return result; }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="test.chenj.study_3_1.MainActivity"> <test.chenj.study_3_1.MyTextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff666666" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /></LinearLayout>
下图时分别设置宽和高为wrap_content,200dp,match_parent时的程序运行效果:
可以发现,当指定wrap_content属性时,View就获得了一个默认的200px,而不是填充父布局了。
- Android View的测量
- View的测量
- view的测量
- Android View的测量
- View的测量
- View的测量
- View的测量
- Android View的测量
- View的测量
- View的测量
- 自定义View的测量
- view的测量
- View的测量
- 关于View的测量
- View的测量
- view的测量
- View的测量 绘制
- View的测量
- 借助BMFont来实现图片变文字
- centos7安装ffmpeg
- PHP版今日头条算法面试题(持续更新)
- 字符串右截断
- 初识Kotlin(一)
- View的测量
- jquery 中substring,substr,split的用法
- 跨域资源共享 CORS 详解
- linux整理
- <机器学习实战 >KNN算法 改进约会网站的配对效果
- MySQL数据库中怎么把表中的整列的字符串换格式
- 2017年12月7号的工作总结
- QT控件大全 七 QProg
- hadoop环境配置