学习篇---FlowLayout的实现

来源:互联网 发布:excel数据提取工具 编辑:程序博客网 时间:2024/06/10 00:53

FlowLayout,通过自定义ViewGroup来实现,主要重写的onMeasure()和onLayout()方法;onMeasure()作用是计算自定义ViewGroup中控件的大小,从而确定自定义布局的with和height。onLayout()作用是对自定义ViewGroupz中的控件进行定位。

效果图:

FlowLayout.java:

public class FlowLayout extends ViewGroup {    public FlowLayout(Context context) {        this(context, null);    }    public FlowLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int layoutWithSize = MeasureSpec.getSize(widthMeasureSpec);        int layoutWithMode = MeasureSpec.getMode(widthMeasureSpec);        int layoutHeightSize = MeasureSpec.getSize(heightMeasureSpec);        int layoutHeightMode = MeasureSpec.getMode(heightMeasureSpec);        int layoutWith = 0;        int layoutHeight = 0;        int lineWith = 0;        int lineHeight = 0;        int childCount = getChildCount();        for (int i = 0; i < childCount; i++) {            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);            MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getChildAt(i).getLayoutParams();            int childWith = getChildAt(i).getMeasuredWidth() + marginLayoutParams.rightMargin + marginLayoutParams.leftMargin;            int childHeight = getChildAt(i).getMeasuredHeight() + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;            if (lineWith + childWith > layoutWithSize-getPaddingLeft()-getPaddingRight()) {                layoutWith = Math.max(layoutWith, lineWith);                lineWith = childWith;                layoutHeight += lineHeight;                lineHeight = childHeight;            } else {                lineWith += childWith;                lineHeight = Math.max(lineHeight, childHeight);            }            if (i == childCount - 1) {                layoutHeight += lineHeight;                layoutWith = Math.max(layoutWith, childWith);            }        }        Log.e("layoutHeight", layoutHeight + "");        Log.e("layoutWith", layoutWith + "");        Log.e("layoutWithSize", layoutWithSize + "");        setMeasuredDimension(layoutWithMode == MeasureSpec.EXACTLY ? layoutWithSize : layoutWith+getPaddingLeft()+getPaddingRight(), layoutHeightMode == MeasureSpec.EXACTLY ? layoutHeightSize : layoutHeight+getPaddingTop()+getPaddingBottom());    }    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        return new MarginLayoutParams(getContext(), attrs);    }    //存放每行的高    private List<Integer> lineHeightList = new ArrayList<>();    //存放每行view的list的list    private List<List<View>> allViews= new ArrayList<>();    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        lineHeightList.clear();        allViews.clear();        int lineHeght = 0;        int lineWith = 0;        List<View> lineViews = new ArrayList<>();        for (int i = 0; i < getChildCount(); i++) {            View child = getChildAt(i);            MarginLayoutParams marginLayoutParams = (MarginLayoutParams) child.getLayoutParams();            int childHeight = child.getMeasuredHeight();            int childWith = child.getMeasuredWidth();            if (lineWith + childWith + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin > getWidth()-getPaddingLeft()-getPaddingRight()) {                lineHeightList.add(lineHeght);                allViews.add(lineViews);                lineViews = new ArrayList<>();                lineWith = 0;                lineHeght = childHeight + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;            }            lineWith += childWith + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;            lineHeght = Math.max(lineHeght, childHeight + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin);            lineViews.add(child);        }        lineHeightList.add(lineHeght);        allViews.add(lineViews);        int lineNum = allViews.size();        int left=getPaddingLeft();        int top=getPaddingTop();        for (int i = 0; i < lineNum; i++)        {            // 当前行的所有的View            lineViews = allViews.get(i);            lineHeght = lineHeightList.get(i);            for (int j = 0; j < lineViews.size(); j++)            {                View child = lineViews.get(j);                // 判断child的状态                if (child.getVisibility() == View.GONE)                {                    continue;                }                MarginLayoutParams lp = (MarginLayoutParams) child                        .getLayoutParams();                int lc = left + lp.leftMargin;                int tc = top + lp.topMargin;                int rc = lc + child.getMeasuredWidth();                int bc = tc + child.getMeasuredHeight();                // 为子View进行布局                child.layout(lc, tc, rc, bc);                left += child.getMeasuredWidth() + lp.leftMargin                        + lp.rightMargin;            }            left = getPaddingLeft();            top += lineHeght ;        }    }

0 0