自定义ViewGroup之FlowLayout

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yoonerloop/article/details/86618668

 

先看看效果图:

先自定义一个类TestViewGroup,继承自ViewGroup,重写onMeasure、onLayout方法。

一、重写onMeasure方法

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

1、获取该ViewGroup的尺寸信息

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

2、测量子view

measureChildren(widthMeasureSpec, heightMeasureSpec);

3、遍历子view

4、获取子view尺寸信息

5、设置每行每列的宽高信息

6、设置子view的四个顶点尺寸信息

7、最后设置setMeasuredDimension

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //测量子View
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        //记录总宽、总高:初始值为 -50,因为后面间距每个需要增加50
        int lineWidth = -widthSpacing;
        int lineHeight = -heightSpacing;
        //子View的宽高
        int cHeight;
        int cWidth;
        //遍历子View
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            //获取每个View的实际宽
            cWidth = view.getMeasuredWidth();
            cHeight = view.getMeasuredHeight();
            if (lineWidth + cWidth  > widthSize) {
                //如果超出父布局,则换行,高度新增,宽度从0开始:每次竖向距离增加50
                lineHeight = lineHeight + cHeight + heightSpacing;
                lineWidth = -widthSpacing;
            } else {
                //否则使用原有的宽高
                lineHeight = Math.max(lineHeight, cHeight);
            }
            //宽度累加:增加50间距,横向距离
            lineWidth = cWidth + widthSpacing + lineWidth;
            //设置边距
            view.setLeft(lineWidth - cWidth);
            view.setRight(lineWidth);
            view.setTop(lineHeight - cHeight);
            view.setBottom(lineHeight);
        }
        //宽高变化后进行设置
        setMeasuredDimension(widthSize, lineHeight);
    }

每个步骤上面有详细的步骤信息备注,上面的heightSpacing 为设置每行间距,widthSpacing为每列间距,这么默认可以设置一个默认值,也可以提供一个方法对外暴露来使用。

二、onLayout

遍历每个view逐个设置。

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = getChildAt(i);
            if (view.getVisibility() != View.GONE) {
                //逐个绘制
                view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
            }
        }
    }

三、使用

这里直接写在XML里面,也可以动态添加布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="40dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="自定义ViewGroup"
        android:textColor="@android:color/black"
        android:textSize="24sp"/>

    <com.viewgroup.viewgroupdemo.TestViewGroup
        android:id="@+id/viewgroup"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_marginTop="50dp">

        <TextView
            style="@style/textstyle"
            android:layout_height="30dp"
            android:text="铁总回应高铁飙车"/>

        <TextView
            style="@style/textstyle"
            android:text="腾讯大王卡"
            />

        <TextView
            style="@style/textstyle"
            android:text="苹果8降价"
            />

        <TextView
            style="@style/textstyle"
            android:text="王者荣耀6"
            />

        <TextView
            style="@style/textstyle"
            android:background="@drawable/shape_text_bg"
            android:text="张三2"
            />

       …………………………………………………………………………………………………………………………………………


    </com.viewgroup.viewgroupdemo.TestViewGroup>
</LinearLayout>

源代码地址:https://download.csdn.net/download/yoonerloop/10935103

今年最后一篇文章,祝大家新春快乐,万事如意!

猜你喜欢

转载自blog.csdn.net/yoonerloop/article/details/86618668