android流式布局:FlexboxLayout用法探析(一)

时间:2021-11-07 05:25:11

FlexboxLayout是google官方开源的一个可以简单快速创建具有弹性功能的流式布局,它的目的是使用我们常见的布局模式,帮我们很好的实现UI区域的比例划分,比如三列布局,可以非常简单的实现。它支持非常多的属性设置,用起来很简单。

GitHub:https://github.com/google/flexbox-layout


首先引入该库:

dependencies {
    compile 'com.google.android:flexbox:0.2.2'
}
然后是在布局文件中声明使用该控件:

<com.google.android.flexbox.FlexboxLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:flexDirection="row"
    app:flexWrap="wrap"
    app:justifyContent="flex_start">

    <TextView
        style="@style/TextViewStyle"
        android:text="我是谁?" />

    <TextView
        style="@style/TextViewStyle"
        android:text="我从哪里来?" />

    <TextView
        style="@style/TextViewStyle"
        android:text="我又将到哪里去呢?" />
    <TextView
        style="@style/TextViewStyle"
        android:text="To be or not to be," />

    <TextView
        style="@style/TextViewStyle"
        android:text="that is the question." />

    <TextView
        style="@style/TextViewStyle"
        android:text="哼哼,凡人!" />
</com.google.android.flexbox.FlexboxLayout>

其中,TextViewStyle如下:

    <style name="TextViewStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:background">@drawable/round_corner_rect</item>
        <item name="android:gravity">center</item>
        <item name="android:padding">10dp</item>
        <item name="android:layout_margin">5dp</item>
    </style>

经过如上代码设置之后,布局显示如图:

android流式布局:FlexboxLayout用法探析(一)

我靠,啥情况,没显示全啊,还都挤在了一行,那就先暂时去掉几个view看看呢,去掉后三个再看看呢,

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

嗯,显示是正常了,但乍一看,也没啥啊,其实不然,这是因为你没有设置属性的原因,先才是重点,属性的设置。具体有哪些属性,可以查看一下源码,下面是一个个的来看一下不同属性的使用方法。

1.flexDirection属性,具体啥用处先装不知道,一会看效果,代码如下:

        <attr name="flexDirection">
            <enum name="row" value="0" />
            <enum name="row_reverse" value="1" />
            <enum name="column" value="2" />
            <enum name="column_reverse" value="3" />
        </attr>
给FlexboxLayout设置当前flexDirection属性,具体不同值产生的不同效果图如下:

(1)设置值为row时:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)与上面的图没啥区别嘛,说明默认的flexDirection的值就是row咯。

(2)设置为row_reverse时:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)发现了没,有变化了,第一个与第三个位置倒过来了,说明啥,布局开始的方向不同

那剩下的两个也不难理解,效果图如下:

(3)设置为column时:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

(4)设置为column_reverse时:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

通过上面4幅图的比较看出:flexDirection属性是设置FlexbodLayout绘制主轴方向的,

row主轴为水平方向,并且绘制方向是从左到右;

row_reverse主轴为水平方向,绘制方向是从右到左;

column主轴为竖直方向,绘制方向是从上到下;

column_reverse主轴为竖直方向,绘制方向是从下到上。


2.flexWrap属性,代码如下

        <attr name="flexWrap">
            <enum name="nowrap" value="0" />
            <enum name="wrap" value="1" />
            <enum name="wrap_reverse" value="2" />
        </attr>
给FlexboxLayout设置当前 flexWrap 属性,具体不同值产生的不同效果图如下:
当你设置了该属性的时候,你会发现,根据以上的布局,不管设置哪个参数都没啥变化,咋了?难道该属性没用,别急,多设置几个子View再试试呢,当时不是注释掉3个吗,现在打开吧,派上用场了。

(1)当设置nowrap时,效果如下

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

视图显示还是有问题啊,看来,系统默认的该属性的值就是它了。android流式布局:FlexboxLayout用法探析(一)

(2)当设置为wrap时,效果如下

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)
android流式布局:FlexboxLayout用法探析(一)

哎吆我靠,终于有令我眼前一亮的变化了,换行了,发现了没?!哈哈。。。

(3)再设置为wrap_reverse时看看:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

又变化了!就是绘制的起始位置发生变化了。

总体大致明白这个属性是干啥的了。说白了就是声明FlexboxLayout是否支持多行,而nowrap就是不支持,默认的就是这个,另外2个都支持多行,只是绘制起始位置不同罢了。

3.justifyContent属相,代码如下:

        <attr name="justifyContent">
            <enum name="flex_start" value="0" />
            <enum name="flex_end" value="1" />
            <enum name="center" value="2" />
            <enum name="space_between" value="3" />
            <enum name="space_around" value="4" />
        </attr>
对于这个属性的使用,官方有一段说明:

        <!--
            Omitting flex-flow property since it's reflected in the parent flex container.
            Set the flexDirection and/or flexWrap to the parent flex container explicitly if you
            want to use the flex-flow similar way to the web.
         -->
大体的意思,就是要和flexDirection,flexWrap结合使用,不知道对不对,还是看效果图吧。

(1)设置为flex_start时:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

很正常啊,说明默认的就是这一个值咯。

(2)flex_end:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

咦,变化了,跑到左边了,看来是靠左对齐嘛

(3)center:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

嗯,这就是居中显示嘛

(4)space_between:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

这个看上去像是两边对齐了吧,效果就是这样的!

(5)space_around:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

这个可以看做是(3)与(4)的结合体,居中显示并且距离边缘有一定的间隔!

到这里呢,你应该可以大体明白了,这个属性的作用是调整子view 的相对于父布局的对齐方式。

4.alignItems属性:代码如下

        <attr name="alignItems">
            <enum name="flex_start" value="0" />
            <enum name="flex_end" value="1" />
            <enum name="center" value="2" />
            <enum name="baseline" value="3" />
            <enum name="stretch" value="4" />
        </att
当前属性是干啥,但是根据名字中的Items来看,应该是关系到子view的,下面一一来看下效果(事先说明一下在,按照当前的布局,你会发现这是啥玩意,怎么又没变化了,其实不然,据我多方考证,这个属性大概或许可能在父布局FlexboxLayout设置确定值之后才会有效果,下面效果图是把高度确定一下的效果图)

(1)flex_start:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

从图上看出,在高度确定之后,行与行之间是留有间隔的,并且貌似是大小相等的,绘制的起始位置是在整个区域顶部从头开始的。

(2)flex_end:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

可以说与flex_start正好相反,就是绘制的位置是从底部结尾开始的,即底部开始绘制,行与行之间也是有间隔的并且相同。

(3)center:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

这个看出,子view的整体绘制区域是在中心位置。

(4)baseline:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

这个与flex_start的效果是相同的

(5)stretch:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

这这什么情况,高度被占满了,说明这个值是这个意思,不管你父布局有多高,子view的所有高度必须和你相同!

通过以上说明,alignItems属性可以理解为,设置行属性的,行的间隔,行的高度,行绘制的区域规划。

5.alignContent属性,代码如下:

        <attr name="alignContent">
            <enum name="flex_start" value="0" />
            <enum name="flex_end" value="1" />
            <enum name="center" value="2" />
            <enum name="space_between" value="3" />
            <enum name="space_around" value="4" />
            <enum name="stretch" value="5" />
        </attr>
不啰嗦,不逼逼了,直接上图(说明:这个属性好像不可以和 alignItems共用,也可能打开的方式不对,可以自行再验证

(1)flex_start:

android流式布局:FlexboxLayout用法探析(一)

很正常,没看出啥来!

(2)flex_end:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

出事了,绘制区域是从底部开始的,可以看为绘制区域占用从底部开始。

(3)center:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

绘制区域占用中间位置,我们要处于核心地带。

(4)space_between:

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)

占用了整个绘制区域,并且上下不能留有空白,就是说从开始到结束。

(5)space_around:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

占用整个区域,上下留有空白,意思是说,上下留点位置,剩下的你都占满吧。

(6)stretch:

android流式布局:FlexboxLayout用法探析(一)

android流式布局:FlexboxLayout用法探析(一)android流式布局:FlexboxLayout用法探析(一)

占用整个区域,并且行高变化,所有行充满整个父布局高度,简单点说,你多大,我们就多大。

以上发现,这个属性是针对子view中所占行的调整,即对填充view做整体的调整。


小结说明:

(1)flexDirection:确定view的绘制排列方式的

(2)flexWrap:是否支持多行显示

(3)justifyContent:调整view相对于父布局的对齐方式

(4)alignItems:子view的绘制方式,除了stretch整个值之外,其余的都是根据公式计算出行与行之间的间隔来确定子view的绘制

(5)alignContent:对内容绘制区域的设置。


以上截图都是在flexDirection=“row”下截的,其中对于未确定高度的情况下alignItems与alignContent没有实际的意义,赶脚