美文网首页
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的实现

    今天我来说下android如何实现流式布局。 先分析下如何实现这样的效果,首先肯定是要自定义一个ViewGroup...

  • Android 自定义ViewGroup之实现FlowLayou

    本篇文章讲的是Android 自定义ViewGroup之实现标签流式布局-FlowLayout,开发中我们会经常需...

  • Android FlowLayout 流式布局

    FlowLayout 流式布局 Android 流式布局控件,实现自动换行,操出范围可以滑动功能,未使用控件复用功...

  • FlowLayout

    Android中的FlowLayout~ 相信大家在Java的图形化界面中,经常使用到FlowLayout,flo...

  • Android view的测绘练习-流式布局-FlowLayou

    Android View的测量 最好先了解一下 FlowLayout源码 这次要实现的功能先看一下FlowLayo...

  • flowlayout

    package com.example.flowlayout; import android.content.Co...

  • 流式布局FlowLayout

    实现效果如图 public class FlowLayout extends ViewGroup {public ...

  • FlowLayout:Android自定义ViewGroup实现

    需求 我们需要实现一个自定义的Layout,该Layout可以容纳若干个宽高不等的子元素,元素按照从左到右的顺序排...

  • Android Customize FlowLayout

    流布局相信大家应该都比较清楚,几乎每个人都写过。开源的也是非常多!就不过多介绍啦,这里做了一个比较简洁且支持Pad...

  • Android - 居中的FlowLayout

    前言 因为需求的原因,需要去使用流式布局,但是这次我们的需求,和我之前的见到的流式布局不太一样。因为我们的是居中显...

网友评论

      本文标题:Android FlowLayout的实现

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