返回
Android View 测量详解
Android
2023-09-04 15:35:59
概述
Android View 测量是确定 View 大小和位置的过程。它由父容器(ViewGroup)调用,以确定其子 View 的大小和位置。测量结果由 View 的 layout() 方法使用,以将 View 放置在正确的位置。
测量规范
测量规范是一个包含两个值的结构,用于指定 View 的测量约束。这两个值分别是:
- 宽度规范 (widthMeasureSpec) :指定 View 在水平方向上可以使用的最大宽度。
- 高度规范 (heightMeasureSpec) :指定 View 在垂直方向上可以使用的最大高度。
每个规范值都由两个标志位和一个数字组成:
- 标志位 (specMode) :指定 View 在该方向上的测量模式。它可以是以下三种之一:
- UNSPECIFIED :View 在该方向上没有约束,可以是任何大小。
- EXACTLY :View 在该方向上的大小被精确指定,必须是指定的大小。
- AT_MOST :View 在该方向上的大小不能超过指定的大小,但可以小于指定的大小。
- 数字 (specSize) :指定 View 在该方向上可以使用的最大值。
测量流程
测量流程如下:
- 父容器调用子 View 的 measure() 方法。
- 子 View 根据测量规范和自己的测量规则计算其大小。
- 子 View 将其计算的大小返回给父容器。
- 父容器使用子 View 返回的大小来确定子 View 的位置。
测量模式
测量模式有三种:UNSPECIFIED、EXACTLY 和 AT_MOST。
- UNSPECIFIED :View 在该方向上没有约束,可以是任何大小。这种模式通常用于 View 的根布局。
- EXACTLY :View 在该方向上的大小被精确指定,必须是指定的大小。这种模式通常用于 View 的子布局。
- AT_MOST :View 在该方向上的大小不能超过指定的大小,但可以小于指定的大小。这种模式通常用于 View 的子布局,以确保子 View 的大小不超过父容器的大小。
测量示例
下面是一个测量示例,展示了如何测量一个 FrameLayout。
public class MyFrameLayout extends FrameLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 获取子 View 的个数
int childCount = getChildCount();
// 计算 FrameLayout 的宽度和高度
int width = 0;
int height = 0;
// 遍历子 View,并计算 FrameLayout 的宽度和高度
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
// 测量子 View
measureChild(child, widthMeasureSpec, heightMeasureSpec);
// 计算 FrameLayout 的宽度和高度
width = Math.max(width, child.getMeasuredWidth());
height = Math.max(height, child.getMeasuredHeight());
}
// 设置 FrameLayout 的宽度和高度
setMeasuredDimension(width, height);
}
}
在上面的示例中,FrameLayout 的宽度和高度是根据子 View 的宽度和高度计算的。FrameLayout 的宽度是子 View 中最宽的子 View 的宽度,FrameLayout 的高度是子 View 中最高子 View 的高度。