自定义ViewGroup实现流式布局

FlowLayout 自定义布局
本文介绍了一个自定义的 FlowLayout 布局实现,该布局能够使子视图自动换行排列,适用于 Android 开发中复杂界面布局的需求。
package com.example.test;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class FlowLayout extends ViewGroup {

	private int lineSpacing = 20;

	public FlowLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

		int paddingLeft = getPaddingLeft();
		int paddingRight = getPaddingRight();
		int paddingTop = getPaddingTop();
		int paddingBottom = getPaddingBottom();

		int widthUsed = paddingLeft + paddingRight;
		int heightUsed = paddingTop + paddingBottom;

		int childMaxHeightOfThisLine = 0;
		int childCount = getChildCount();
		for (int i = 0; i < childCount; i++) {
			View child = getChildAt(i);
			if (child.getVisibility() != GONE) {
				int childUsedWidth = 0;
				int childUsedHeight = 0;

				measureChild(child, widthMeasureSpec, heightMeasureSpec);

				childUsedWidth += child.getMeasuredWidth();
				childUsedHeight += child.getMeasuredHeight();

				FlowLayoutParams params = (FlowLayoutParams) child
						.getLayoutParams();

				childUsedWidth += params.leftMargin + params.rightMargin;
				childUsedHeight += params.topMargin + params.bottomMargin;

				if (widthUsed + childUsedWidth < widthSpecSize) {
					widthUsed += childUsedWidth;
					if (childUsedHeight > childMaxHeightOfThisLine) {
						childMaxHeightOfThisLine = childUsedHeight;
					}
				} else {
					heightUsed += childMaxHeightOfThisLine + lineSpacing;
					widthUsed = paddingLeft + paddingRight + childUsedWidth;
					childMaxHeightOfThisLine = childUsedHeight;
				}
			}
		}
		heightUsed += childMaxHeightOfThisLine;
		setMeasuredDimension(widthSpecSize, heightUsed);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int paddingLeft = getPaddingLeft();
		int paddingRight = getPaddingRight();
		int paddingTop = getPaddingTop();

		int childStartLayoutX = paddingLeft;
		int childStartLayoutY = paddingTop;

		int widthUsed = paddingLeft + paddingRight;

		int childMaxHeight = 0;

		int childCount = getChildCount();

		for (int i = 0; i < childCount; i++) {
			View child = getChildAt(i);
			if (child.getVisibility() != GONE) {
				int childNeededWidth, childNeedHeight;
				int left, top, right, bottom;

				int childMeasuredWidth = child.getMeasuredWidth();
				int childMeasuredHeight = child.getMeasuredHeight();

				FlowLayoutParams params = (FlowLayoutParams) child
						.getLayoutParams();

				int childLeftMargin = params.leftMargin;
				int childTopMargin = params.topMargin;
				int childRightMargin = params.rightMargin;
				int childBottomMargin = params.bottomMargin;

				childNeededWidth = childLeftMargin + childRightMargin
						+ childMeasuredWidth;
				childNeedHeight = childTopMargin + childBottomMargin
						+ childMeasuredHeight;

				if (widthUsed + childNeededWidth <= r - l) {
					if (childNeedHeight > childMaxHeight) {
						childMaxHeight = childNeedHeight;
					}
				} else {
					childStartLayoutY += childMaxHeight + lineSpacing;
					childStartLayoutX = paddingLeft;
					childMaxHeight = childNeedHeight;
					widthUsed = paddingLeft + paddingRight;
				}

				left = childStartLayoutX + childLeftMargin;
				top = childStartLayoutY + childTopMargin;
				right = left + childMeasuredWidth;

				bottom = top + childMeasuredHeight;
				widthUsed += childNeededWidth;
				childStartLayoutX += childNeededWidth;

				child.layout(left, top, right, bottom);
			}
		}
	}

	@Override
	protected LayoutParams generateLayoutParams(LayoutParams p) {
		return new FlowLayoutParams(p);
	}

	@Override
	public LayoutParams generateLayoutParams(AttributeSet attrs) {
		return new FlowLayoutParams(getContext(), attrs);
	}

	private class FlowLayoutParams extends MarginLayoutParams {

		public FlowLayoutParams(int arg0, int arg1) {
			super(arg0, arg1);
		}

		public FlowLayoutParams(LayoutParams arg0) {
			super(arg0);
		}

		public FlowLayoutParams(MarginLayoutParams arg0) {
			super(arg0);
		}

		public FlowLayoutParams(Context arg0, AttributeSet arg1) {
			super(arg0, arg1);
		}

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值