前言
最近接触了自定义ViewGroup,准备写一个自定义流式布局练练手,流式布局广泛应用于安卓开发中,许多APP的历史记录就应用了这一模式 
一、如何实现?
需要去继承ViewGroup,重写ViewGroup的方法
二、使用步骤
1.重写onMeasure方法
代码如下:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initLines();
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(widthMeasureSpec);
int width = 0;
int height = 0;
int lineWidth = 0;
int lineHeight = 0;
List<View> lineViews = new ArrayList<>();
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
LayoutParams childLayoutParams = childView.getLayoutParams();
int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight(), childLayoutParams.width);
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom(), childLayoutParams.height);
childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
int childMeasureWidth = childView.getMeasuredWidth();
int childMeasureHeight = childView.getMeasuredHeight();
if (lineWidth + childMeasureWidth + HORIZONTAL_SPACING > sizeWidth) {
allLines.add(lineViews);
allLinesHeight.add(lineHeight);
width = Math.max(lineWidth, width);
height = height + lineHeight;
lineWidth = childMeasureWidth + HORIZONTAL_SPACING;
lineHeight = childMeasureHeight;
lineViews = new ArrayList<>();
} else {
lineHeight = Math.max(lineHeight, childMeasureHeight);
lineWidth = lineWidth + childMeasureWidth + HORIZONTAL_SPACING;
}
lineViews.add(childView);
if (i == getChildCount() - 1) {
allLines.add(lineViews);
allLinesHeight.add(lineHeight);
width = Math.max(width, lineWidth);
height = height + childMeasureHeight + VERTICAL_SPACING;
}
}
int realWidth = (modeWidth == MeasureSpec.EXACTLY) ? sizeWidth : width;
int realHeight = (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight : height;
setMeasuredDimension(realWidth, realHeight);
}
2.重写onLayout
代码如下(示例):
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int curT = getPaddingTop();
int curL = getPaddingLeft();
for (int i = 0; i < allLines.size(); i++) {
for (int j = 0; j < allLines.get(i).size(); j++) {
View view = allLines.get(i).get(j);
int left = curL;
int right = left + view.getMeasuredWidth();
int top = curT;
int bottom = top + view.getMeasuredHeight();
view.layout(left, top, right, bottom);
curL = right + HORIZONTAL_SPACING;
}
curT = curT + allLinesHeight.get(i) + VERTICAL_SPACING;
curL = getPaddingLeft();
}
}
3,效果展示

三、项目代码
点击下载
总结
onMeasure给每个View和ViewGroup规划好大小
onLayout给每个View摆放位置
|