Android 自定义UI 实战 02 流式布局


前言

================================================================

使用纯代码 加 注释的方式,可以更快的理解源码

如果你喜欢,请点个赞,后期会不断的深入讲解


1、自定义控件,并在XML 使用


自定一个Layout 继承 ViewGroup


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 onLayout(boolean b, int i, int i1, int i2, int i3) {



    }

}





在Layout 中使用组件,我这里简单的写了一些数据测试


<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">



    <com.traveleasy.leaningui02.FlowLayout xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:app="http://schemas.android.com/apk/res-auto"

        xmlns:tools="http://schemas.android.com/tools"

        android:id="@+id/mFlowLayout"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:layout_margin="10dp"

        tools:ignore="MissingClass">



        <Button

            android:layout_width="wrap_content"

            android:layout_height="55dp"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="100dp"

            android:text="一行一个元素生活不止眼前的苟且,还有诗和远方大法师的打分sad发送到发送到发的发送到发送到第三方阿萨德佛挡杀佛但是" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="90dp"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:text="11一行一个元素生活不止眼前的苟且,还有诗和远方大法师的打分sad发送到发送到发的发送到发送到第三方阿萨德佛挡杀佛但是" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="85dp"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="45dp"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="75dp"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="60dp"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="85dp"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="100dp"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="85dp"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="85dp"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="65dp"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="100dp"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="75dp"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="80dp"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="300dp"

            android:text="生活不止眼前的苟且,还有诗和远方" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="小麻小儿郎呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello hi ..." />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="你是谁呀" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="65dp"

            android:layout_gravity="bottom"

            android:text="人在他在,塔亡人亡" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="生活不止眼前的苟且,还有诗和远方1" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="250dp"

            android:text="发电房" />



        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="这是结束" />

    </com.traveleasy.leaningui02.FlowLayout>



</ScrollView>



2、初始化存储


初始化三个数组,用于存储行数据,所有的行数据,行高


//    每一行的view

    private List<View> mLineView;

//    所有的行,一行一行的存储

    private List<List<View>> mViews;

//    每一行的高度

    private List<Integer> mHeights;




    private void init() {

        mLineView = new ArrayList<>();

        mViews = new ArrayList<>();

        mHeights = new ArrayList<>();

    }



3、测量


重新 onMeasure() 方法,测量view 的属性

源码的解释,都在代码中,如下:


       @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//        获取限制的值

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);



        int heightNode = MeasureSpec.getMode(heightMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);



//        记录当前行的宽度和高度

        int lineWidth = 0;      //宽度是当前行子view 宽度的和

        int lineHeight = 0;     //高度是当前行所有子view 中高度的最大值



//        整个流式布局的宽度和高度

        int flowLayoutWidth = 0;  // 所有行中宽度的最大值

        int flowLayoutHeight = 0; // 所有行的高度的累加



        init();



//        获取到当前的所有child 数量

        int childCount = this.getChildCount();



//        先测量子View,再根据子View 尺寸, 计算自己的

        for (int i = 0; i < childCount; i++) {

            View child = this.getChildAt(i);

            measureChild(child, widthMeasureSpec, heightMeasureSpec);



//            获取到当前子View 的测量高度 和 宽度

            int childWidth = child.getMeasuredWidth();

            int childHeight = child.getMeasuredHeight();



//            已经放入的子 view 的宽度 + 准备放入的子 view 的宽度 大于 总宽度,就换行

            if (lineWidth + childWidth > widthSize) {

                mViews.add(mLineViews);

//                创建 新的一行

                mLineViews = new ArrayList<>();

//                所有行中,最宽的一行,作为流式布局的宽

                flowLayoutWidth = Math.max(flowLayoutWidth, lineWidth);

//                流式布局的高度,为所有行的高度相加

                flowLayoutHeight += lineHeight;

                mHeights.add(lineHeight);

                lineHeight = 0;

                lineWidth = 0;

            }

//            当前行添加子view

            mLineViews.add(child);

//            已有行宽,添加当前 子 view 的宽

            lineWidth += childWidth;



//            获取行中最高的子 View

            lineHeight = Math.max(lineHeight, childHeight);

        }



//        保存尺寸给后面使用

        setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : flowLayoutWidth,

                heightNode == MeasureSpec.EXACTLY ? heightSize : flowLayoutHeight);

    }





4、布局处理



  @Override

    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int currX = 0;

        int currY = 0;

        int lineCount = mViews.size();

//        处理每一行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值