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>
经过如上代码设置之后,布局显示如图:
我靠,啥情况,没显示全啊,还都挤在了一行,那就先暂时去掉几个view看看呢,去掉后三个再看看呢,
嗯,显示是正常了,但乍一看,也没啥啊,其实不然,这是因为你没有设置属性的原因,先才是重点,属性的设置。具体有哪些属性,可以查看一下源码,下面是一个个的来看一下不同属性的使用方法。
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时:
与上面的图没啥区别嘛,说明默认的flexDirection的值就是row咯。
(2)设置为row_reverse时:
发现了没,有变化了,第一个与第三个位置倒过来了,说明啥,布局开始的方向不同
那剩下的两个也不难理解,效果图如下:
(3)设置为column时:
(4)设置为column_reverse时:
通过上面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时,效果如下
视图显示还是有问题啊,看来,系统默认的该属性的值就是它了。
(2)当设置为wrap时,效果如下
哎吆我靠,终于有令我眼前一亮的变化了,换行了,发现了没?!哈哈。。。
(3)再设置为wrap_reverse时看看:
又变化了!就是绘制的起始位置发生变化了。
总体大致明白这个属性是干啥的了。说白了就是声明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时:
很正常啊,说明默认的就是这一个值咯。
(2)flex_end:
咦,变化了,跑到左边了,看来是靠左对齐嘛
(3)center:
嗯,这就是居中显示嘛
(4)space_between:
这个看上去像是两边对齐了吧,效果就是这样的!
(5)space_around:
这个可以看做是(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:
从图上看出,在高度确定之后,行与行之间是留有间隔的,并且貌似是大小相等的,绘制的起始位置是在整个区域顶部从头开始的。
(2)flex_end:
可以说与flex_start正好相反,就是绘制的位置是从底部结尾开始的,即底部开始绘制,行与行之间也是有间隔的并且相同。
(3)center:
这个看出,子view的整体绘制区域是在中心位置。
(4)baseline:
这个与flex_start的效果是相同的
(5)stretch:
这这什么情况,高度被占满了,说明这个值是这个意思,不管你父布局有多高,子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:
很正常,没看出啥来!
(2)flex_end:
出事了,绘制区域是从底部开始的,可以看为绘制区域占用从底部开始。
(3)center:
绘制区域占用中间位置,我们要处于核心地带。
(4)space_between:
占用了整个绘制区域,并且上下不能留有空白,就是说从开始到结束。
(5)space_around:
占用整个区域,上下留有空白,意思是说,上下留点位置,剩下的你都占满吧。
(6)stretch:
占用整个区域,并且行高变化,所有行充满整个父布局高度,简单点说,你多大,我们就多大。
以上发现,这个属性是针对子view中所占行的调整,即对填充view做整体的调整。
小结说明:
(1)flexDirection:确定view的绘制排列方式的
(2)flexWrap:是否支持多行显示
(3)justifyContent:调整view相对于父布局的对齐方式
(4)alignItems:子view的绘制方式,除了stretch整个值之外,其余的都是根据公式计算出行与行之间的间隔来确定子view的绘制
(5)alignContent:对内容绘制区域的设置。
以上截图都是在flexDirection=“row”下截的,其中对于未确定高度的情况下alignItems与alignContent没有实际的意义,赶脚!