600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > android自定义view onmeasure Android自定义View onMeasure 方法

android自定义view onmeasure Android自定义View onMeasure 方法

时间:2019-12-25 20:13:34

相关推荐

android自定义view onmeasure Android自定义View onMeasure 方法

onMeasure 作用

1.一般情况重写onMeasure()方法作用是为了自定义View尺寸的规则,如果你的自定义View的尺寸是根据父控件行为一致,就不需要重写onMeasure()方法

2.如果不重写onMeasure方法,那么自定义view的尺寸默认就和父控件一样大小,当然也可以在布局文件里面写死宽高,而重写该方法可以根据自己的需求设置自定义view大小

认识 onMeasure

1.onMeasure (int widthMeasureSpec, int heightMeasureSpec)是view自己的方法

2.onMeasure 方法简单的理解就是是用于测量视图的大小,主要是用来测量自己和内容的来确定宽度和高度

3.onMeasure有两个参数 ( int widthMeasureSpec, int heightMeasureSpec),该参数表示控件可获得的空间以及关于这个空间描述的元数据.

4.widthMeasureSpec和heightMeasureSpec这两个值通常情况下都是由父视图经过计算后传递给子视图的,说明父视图会在一定程度上决定子视图的大小。

认识 MeasureSpec

在测量自定义view的大小之前,我们需要认识一个类MeasureSpec,它封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求MeasureSpec由size和mode组成。

specMode一共有三种类型,如下所示:

EXACTLY

表示父视图希望子视图的大小应该是由specSize的值来决定的,系统默认会按照这个规则来设置子视图的大小,简单的说(当设置width或height为match_parent时,模式为

EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的)

AT_MOST

表示子视图最多只能是specSize中指定的大小。(当设置为wrap_content时,模式为AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸)

UNSPECIFIED

表示开发人员可以将视图按照自己的意愿设置成任意的大小,没有任何限制。这种情况比较少见,不太会用到。

/**

* 比onDraw先执行

*

* 一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。

* 一个MeasureSpec由大小和模式组成

* 它有三种模式:UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;

* EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;

* AT_MOST(至多),子元素至多达到指定大小的值。

*

* 它常用的三个函数:

* 1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)

* 2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)

* 3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

final int minimumWidth = getSuggestedMinimumWidth();

final int minimumHeight = getSuggestedMinimumHeight();

int width = measureWidth(minimumWidth, widthMeasureSpec);

int height = measureHeight(minimumHeight, heightMeasureSpec);

setMeasuredDimension(width, height);

}

private int measureWidth(int defaultWidth, int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

int width;

switch (specMode) {

case MeasureSpec.AT_MOST:

//指定wrap_content时的宽度,这里的500一个替换为

//该View宽度设置为wrap_content时,View保持完整

//性的最小宽度。

width = 500 + getPaddingLeft() + getPaddingRight();

break;

case MeasureSpec.EXACTLY:

width = specSize;

break;

case MeasureSpec.UNSPECIFIED:

width = Math.max(defaultWidth, specSize);

default:

width = 500;

break;

}

return width;

}

private int measureHeight(int defaultHeight, int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

int height;

switch (specMode) {

case MeasureSpec.AT_MOST:

//同measureWidth相同位置的含义

height = 800 + getPaddingTop() + getPaddingBottom();

break;

case MeasureSpec.EXACTLY:

height = specSize;

break;

case MeasureSpec.UNSPECIFIED:

height = Math.max(defaultHeight, specSize);

break;

default:

height = 800;

break;

}

return height;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。