自己构思实现代码如下:
package hillfly.flowlayout; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * Created by gogolaile on 16/7/5. */ class Flowview extends ViewGroup { public Flowview(Context context) { super(context); } public Flowview(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int x = 0; //宽度坐标 int y = 0; //高度坐标 int row = 0; //行 //先得到流式布局的宽度 int maxWidth = MeasureSpec.getSize(widthMeasureSpec); //得到流失布局的子view的数量 int count = getChildCount(); for(int i=0;i<count;i++){ //得到子view View child = getChildAt(i); //判断如果子view为gone的话不需要显示 if(child.VISIBLE != GONE){ child.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED); //取得子view的宽高 int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); int padleft = child.getPaddingLeft(); int padRight = child.getPaddingRight(); //view放置后,宽度增加子view的宽度 x += width; y = row * height + height; // 如果x超过了最大宽度,子view被放置在下一行 if(x > maxWidth){ x = width; row++; y = row * height + height; } } } //按计算得到的高度设置流式布局 setMeasuredDimension(maxWidth,y); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int x = 0; //宽度坐标 int y = 0; //高度坐标 int row = 0; //行 //先得到流式布局的宽度 int maxWidth = r - 1; //得到流失布局的子view的数量 int count = getChildCount(); for(int i=0;i<count;i++){ //得到子view View child = getChildAt(i); //判断如果子view为gone的话不需要显示 if(child.VISIBLE != GONE){ child.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED); //取得子view的宽高 int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); //view放置后,宽度增加子view的宽度 x += width; y = row * height + height; // 如果x超过了最大宽度,子view被放置在下一行 if(x > maxWidth){ x = width; row++; y = row * height + height; } child.layout(x - width,y - height, x ,y); } } } }但忽略了子view的高度可能不同 ,以及没有加上子view间的间距和流式布局的四边宽度
以下是网上找的实现代码:
public class FlowLayout extends ViewGroup {
private float mVerticalSpacing; //每个item纵向间距
private float mHorizontalSpacing; //每个item横向间距
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setHorizontalSpacing(float pixelSize) {
mHorizontalSpacing = pixelSize;
}
public void setVerticalSpacing(float pixelSize) {
mVerticalSpacing = pixelSize;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int selfWidth = resolveSize(0, widthMeasureSpec);
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int childLeft = paddingLeft;
int childTop = paddingTop;
int lineHeight = 0;
//通过计算每一个子控件的高度,得到自己的高度
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
View childView = getChildAt(i);
LayoutParams childLayoutParams = childView.getLayoutParams();
childView.measure(
getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight,
childLayoutParams.width),
getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom,
childLayoutParams.height));
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
lineHeight = Math.max(childHeight, lineHeight);
if (childLeft + childWidth + paddingRight > selfWidth) {
childLeft = paddingLeft;
childTop += mVerticalSpacing + lineHeight;
lineHeight = childHeight;
} else {
childLeft += childWidth + mHorizontalSpacing;
}
}
int wantedHeight = childTop + lineHeight + paddingBottom;
setMeasuredDimension(selfWidth, resolveSize(wantedHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int myWidth = r - l;
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int childLeft = paddingLeft;
int childTop = paddingTop;
int lineHeight = 0;
//根据子控件的宽高,计算子控件应该出现的位置。
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
View childView = getChildAt(i);
if (childView.getVisibility() == View.GONE) {
continue;
}
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
lineHeight = Math.max(childHeight, lineHeight);
if (childLeft + childWidth + paddingRight > myWidth) {
childLeft = paddingLeft;
childTop += mVerticalSpacing + lineHeight;
lineHeight = childHeight;
}
childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
childLeft += childWidth + mHorizontalSpacing;
}
}
}