美文网首页
Android FlowLayout的实现

Android FlowLayout的实现

作者: xadlovezy | 来源:发表于2018-07-27 15:53 被阅读0次

    今天我来说下android如何实现流式布局。


    image.png

    先分析下如何实现这样的效果,首先肯定是要自定义一个ViewGroup
    然后就是计算View的宽和高,如何获取宽高呢?参照最终效果来分析,

    宽其实就是每一行宽中最大的一个,高就是每一行的高累加。

    如何实现呢,代码走起。。。

    package weight.uztek.customview;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class FlowLly extends ViewGroup {
    
        private List<List<View>> allViews = new ArrayList<>();
    
        //每行的宽度
        private List<Integer> widthList = new ArrayList<>();
    
        //每行的高度
        private List<Integer> heightList = new ArrayList<>();
    
    
        public FlowLly(Context context) {
            super(context);
        }
    
        public FlowLly(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public FlowLly(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            allViews.clear();
            widthList.clear();
            heightList.clear();
    
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    
            int width = 0;
            int height = 0;
    
            //行宽
            int lineWidth = 0;
    
            //行高
            int lineHeight = 0;
    
            measureChildren(widthMeasureSpec, heightMeasureSpec);
    
            int childCount = getChildCount();
    
            List<View> views = new ArrayList<>();//第一行的View
    
            for (int i = 0; i < childCount; i++) {
    
                View childView = getChildAt(i);
                MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();
    
                int childWidth = childView.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;
    
                int childHeight = childView.getMeasuredHeight() + layoutParams.topMargin + layoutParams.bottomMargin;
    
                //判断是否抢换行
                if (lineWidth + childWidth > widthSize) {
                    //换行
                    widthList.add(lineWidth);
                    heightList.add(lineHeight);
                    lineWidth = childWidth;
                    lineHeight = childHeight;
                    allViews.add(views);
                    views = new ArrayList<>();
                    views.add(childView);
                } else {
                    //在同一行
                    lineWidth += childWidth;
                    lineHeight = Math.max(lineHeight, childHeight);
                    views.add(childView);
                }
    
                if(i==childCount-1){
                    widthList.add(lineWidth);
                    heightList.add(lineHeight);
                    allViews.add(views);
                }
    
            }
    
            width = max(widthList);
            height = add(heightList);
            setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width, heightMode == MeasureSpec.EXACTLY ? heightSize : height);
        }
    
        private int max(List<Integer> datas) {
            int max = datas.get(0);
            for (int i : datas) {
                if (i > max)
                    max = i;
            }
            return max;
        }
    
        private int add(List<Integer> datas) {
            int result = 0;
            for (int i : datas) {
                result += i;
            }
            return result;
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int height = 0;
            int width = 0;
            for (int i = 0; i < allViews.size(); i++) {
    
                for (View view : allViews.get(i)) {
    
                    MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
    
                    int left, top, right, bottom;
    
                    left =  width + layoutParams.leftMargin;
    
                    top =  height + layoutParams.topMargin;
    
                    right = left + view.getMeasuredWidth();
    
                    bottom = top + view.getMeasuredHeight();
    
                    width += view.getMeasuredWidth()+layoutParams.leftMargin+layoutParams.rightMargin;
    
                    view.layout(left,top,right,bottom);
    
                }
    
                width=0;
                height += heightList.get(i);
            }
        }
    
        @Override
        public LayoutParams generateLayoutParams(AttributeSet attrs) {
            return new MarginLayoutParams(getContext(), attrs);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Android FlowLayout的实现

          本文链接:https://www.haomeiwen.com/subject/dnlgmftx.html