代码拉取完成,页面将自动刷新
package com.example.myapplication.viewgroup;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ymz0427 on 2021/8/9
*/
public class FlowLayout extends ViewGroup {
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private final int horizontalSpace = dp2px(20);
private final int verticalSpace = dp2px(10);
private final List<List<View>> allLines = new ArrayList<>();
private final List<Integer> heights = new ArrayList<>();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
allLines.clear();
heights.clear();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int usedWidth = 0;
int height = 0;
//父布局对FlowLayout的约束宽高
int seftWidth = MeasureSpec.getSize(widthMeasureSpec) - paddingLeft - paddingRight;
int seftHeight = MeasureSpec.getSize(heightMeasureSpec) - paddingTop - paddingBottom;
//FlowLayout的测量宽高
int needHeight = 0;
int needWidth = 0;
List<View> line = new ArrayList<>();
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight,
child.getLayoutParams().width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom,
child.getLayoutParams().height);
child.measure(childWidthSpec, childHeightSpec);
if (usedWidth + horizontalSpace + child.getMeasuredWidth() > seftWidth) {
//当前行无法在放下下一个view,则保存当前行的Views集合以及当前行的最大高度,
heights.add(height + verticalSpace);
allLines.add(line);
//所有行的最大宽度
needWidth = Math.max(needWidth, usedWidth);
//所有行的高度之和
needHeight += height + verticalSpace;
//重置下一行的使用宽度、高度、View集合
usedWidth = 0;
height = 0;
line = new ArrayList<>();
}
//获取当前行的最大高度,作为当前行的高度
height = Math.max(height, child.getMeasuredHeight());
//记录已经使用的宽度
usedWidth += child.getMeasuredWidth() + (line.size() == 0 ? 0 : horizontalSpace);
//保存已经测量及模拟布局的View
line.add(child);
//记录最后一行的数据
if (i == count - 1) {
heights.add(height + verticalSpace);
allLines.add(line);
needWidth = Math.max(needWidth, usedWidth);
needHeight += height + verticalSpace;
}
}
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//如果mode为MeasureSpec.EXACTLY, 则使用widthMeasureSpec中的size,不然使用测量得到的size, 宽高同理
int realWidth = widthMode == MeasureSpec.EXACTLY ? seftWidth : needWidth;
int realHeight = heightMode == MeasureSpec.EXACTLY ? seftHeight : needHeight;
//保存测量的宽和高
setMeasuredDimension(realWidth + paddingLeft + paddingRight,
realHeight + paddingTop + paddingBottom - (allLines.size() > 0 ? verticalSpace : 0));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = getPaddingLeft();
int top = getPaddingTop();
for (int i = 0; i < allLines.size(); i++) {
List<View> line = allLines.get(i);
for (int j = 0; j < line.size(); j++) {
View child = line.get(j);
child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
left += child.getMeasuredWidth() + horizontalSpace;
}
left = getPaddingLeft();
top += heights.get(i);
}
}
public static int dp2px(int dimen) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimen, Resources.getSystem().getDisplayMetrics());
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。