您的位置:首页 > 移动开发 > Android开发

自定义View学习笔记之onMeasure()方法

2016-08-01 12:26 387 查看
1.为什么要重写onMeasure()方法?

我们拿一个例子来看。自定义一个MyView类并继承View,代码如下:

package com.example.smily.myview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
public MyView(Context context) {
super(context);
}

public MyView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}


在布局文件中声明该自定义View并将layout_width和layout_height设置成match_parent,如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.smily.myview.MainActivity">

<com.example.smily.myview.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"/>
</RelativeLayout>


然后运行程序,发现效果正是我们想要的结果:



接下来,把width和height都设置成wrap_content,按理说这样设置layout_width和layout_height都应该是0才对,但是呢,实际运行的效果图跟上图没有任何变化!

那么问题就出现了,我们明明设置了wrap_content,但为什么效果却和设置match_parent效果一样呢?

其实,我们自定义的MyView继承了父容器(RelativeLayout)的大小!解决这个问题就需要我们重写onMeasure()方法了。

2.onMeasure方法中的参数和与之相关的几个常量都表示什么意思?

(1)onMeasure方法中有两个参数,分别是widthMeasureSpec和heightMeasureSpec,这两个参数表示什么?

这两个参数是View可以获取的宽高尺寸和模式值混合的int数据。可以通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size =MeasureSpec.getSize(widthMeasureSpec)得到尺寸。

(2)通过MeasureSpec.getMode(widthMeasureSpec)我们可以获取到View宽高的模式,这个模式有三个值,分别是:

MeasureSpec.EXACTLY;

MeasureSpec.AT_MOST;

MeasureSpec.UNSPECIFIED.

这三个常量值表示什么意思?

其中MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width=”100dp”,或者为match_parent时,都是控件大小已经确定的情况,都是精确尺寸。

MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。

MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

(3)通过MeasureSpec.getSize()得到的是什么?

MeasureSpec.getSize()会解析MeasureSpec值得到父容器的width或者height。

3.小结:

(1)重写onMeasure()方法是为了自定义View尺寸的规则。

(2)如果自定义View的尺寸是与父控件行为一致,就不需要重写onMeasure()方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android onMeasure