onMeasure里如何重置只有1个子view一行满屏, 若有多个自适应一行
可以尝试在 onMeasure
方法中重写 measureChildWithMargins
或 measureChild
方法来实现这个需求。
对于只有一个字的 View,我们可以把它的宽度设为屏幕宽度,高度设为最大高度,这样这个 View 就会占满一整行。
而对于多个 View 自适应的情况,我们可以先测量每个 View 的宽度,并累加得到它们的总宽度。如果总宽度小于屏幕宽度,那么我们可以将 View 的宽度设为屏幕宽度除以 View 的个数,这样所有 View 的宽度都相同,就可以一行放下了。否则,我们可以默认按原有的宽度进行布局,让它们分成多行。
以下是示例代码:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 获取父容器的尺寸规格
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int childCount = getChildCount();
if (childCount == 1) { // 只有一个 View 的情况
View child = getChildAt(0);
// 让 View 的宽度填满屏幕,高度取最大值
int widthMeasureSpecForChild = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
int heightMeasureSpecForChild = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
child.measure(widthMeasureSpecForChild, heightMeasureSpecForChild);
setMeasuredDimension(widthSize, child.getMeasuredHeight());
} else { // 多个 View 的情况
int totalWidth = 0;
// 计算多个 View 的总宽度
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
int childWidth = child.getMeasuredWidth();
totalWidth += childWidth;
}
// 如果总宽度小于屏幕宽度,让每一个 View 的宽度都为屏幕宽度除以 View 的个数
if (totalWidth < widthSize) {
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize / childCount, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
// 测量自身尺寸并设置
int totalHeight = 0;
int lineWidth = 0;
int lineHeight = 0;
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
// 测量子 View 的尺寸
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
// 计算子 View 的行宽和行高
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
if (lineWidth + childWidth > widthSize) {
totalHeight += lineHeight;
lineWidth = 0;
lineHeight = childHeight;
}
lineWidth += childWidth;
lineHeight = Ma