Android自定义控件--流式布局(FlowLayout)

来源:互联网 发布:java解释器 编辑:程序博客网 时间:2024/04/25 19:56
效果图:
/*
 *首先需要先自定义一个类然后继承ViewGroup
 *然后看看onMeasure()方法的实现
 *然后看看onLayout()方法的实现
 *
 */
import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;public class MyFlowLayout extends ViewGroup {    private int lineSpacing;    public MyFlowLayout(Context context) {        super(context);    }    public MyFlowLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected LayoutParams generateLayoutParams(LayoutParams p) {        return new MarginLayoutParams(p);    }    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs)    {        return new MarginLayoutParams(getContext(), attrs);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        int mPaddingLeft = getPaddingLeft();        int mPaddingRight = getPaddingRight();        int mPaddingTop = getPaddingTop();        int lineX = mPaddingLeft;        int lineY = mPaddingTop;        int lineWidth = r - l;        int usefulWidth = lineWidth - mPaddingLeft - mPaddingRight;        int lineUsed = mPaddingLeft + mPaddingRight;        int lineHeight = 0;        for (int i = 0; i < this.getChildCount(); i++) {            View child = this.getChildAt(i);            if (child.getVisibility() == GONE) {                continue;            }            MarginLayoutParams mlp = (MarginLayoutParams) child.getLayoutParams();            int childWidth = child.getMeasuredWidth();            int childHeight = child.getMeasuredHeight();            int spaceWidth = mlp.leftMargin + childWidth + mlp.rightMargin;            int spaceHeight = mlp.topMargin + childHeight + mlp.bottomMargin;            if (lineUsed + spaceWidth > lineWidth) {                //approach the limit of width and move to next line                lineY += lineHeight + lineSpacing;                lineUsed = mPaddingLeft + mPaddingRight;                lineX = mPaddingLeft;                lineHeight = 0;            }            child.layout(lineX + mlp.leftMargin, lineY + mlp.topMargin, lineX + mlp.leftMargin + childWidth, lineY + mlp.topMargin + childHeight);            if (spaceHeight > lineHeight) {                lineHeight = spaceHeight;            }            lineUsed += spaceWidth;            lineX += spaceWidth;        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int mPaddingLeft = getPaddingLeft();        int mPaddingRight = getPaddingRight();        int mPaddingTop = getPaddingTop();        int mPaddingBottom = getPaddingBottom();        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int lineUsed = mPaddingLeft + mPaddingRight;        int lineY = mPaddingTop;        int lineHeight = 0;        for (int i = 0; i < this.getChildCount(); i++) {            View child = this.getChildAt(i);            if (child.getVisibility() == GONE) {                continue;            }            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, lineY);            MarginLayoutParams mlp = (MarginLayoutParams) child.getLayoutParams();            int childWidth = child.getMeasuredWidth();            int childHeight = child.getMeasuredHeight();            int spaceWidth = mlp.leftMargin + childWidth + mlp.rightMargin;            int spaceHeight = mlp.topMargin + childHeight + mlp.bottomMargin;            if (lineUsed + spaceWidth > widthSize) {                //approach the limit of width and move to next line                lineY += lineHeight + lineSpacing;                lineUsed = mPaddingLeft + mPaddingRight;                lineHeight = 0;            }            if (spaceHeight > lineHeight) {                lineHeight = spaceHeight;            }            lineUsed += spaceWidth;        }        setMeasuredDimension(                widthSize,                heightMode == MeasureSpec.EXACTLY ? heightSize : lineY + lineHeight + mPaddingBottom        );    }}
/*
 *
 *activity_main.xml页面
 */
<com.bawei.view.MyFlowLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.bawei.day04_demo_zuoye01_flowlayout.MainActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@color/colorAccent"        android:layout_marginTop="5dp"        android:text="你好" />
</com.bawei.view.MyFlowLayout>