FlexboxLayout 是google出品的Android控件,类似前端或RN的flex布局。
FlexboxLayout 分为主轴和侧轴(垂直于主轴)。flexDirection属性(row,row_reverse,column,column_reverse)决定的。
FlexboxLayout属性主要有两部分。一是本身这个ViewGroup的属性,一是它内部Item的属性。
flex lines表示主轴是row(或row_reverse)时候的一行或column(column_reverse)时候的一列。
简单使用
代码,就添加了一个flexWrap属性
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap"
android:background="#f5f5f5">
···
</com.google.android.flexbox.FlexboxLayout>
效果如下,我们发现跟FlowLayout类似。下面在看下还有哪些属性,可以实现什么样的效果呢。
FlexboxLayout的属性
1,flexWrap
这个属性控制flex容器是单行还是多行显示,还是侧轴上的方向
nowrap(默认) (显示单行)
wrap (显示多行)
wrap_reverse (flex lines翻转,后面会说)
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexWrap="wrap/nowrap/wrap_reverse">
<TextView
style="@style/flex_common_style"
android:text="1"/>
<TextView
style="@style/flex_common_style"
android:text="2"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
测试效果
2,flexDirection
该属性确定了主轴的方向。属性有
row (默认的)
row_reverse
column
column_reverse
默认的row属性跟FlowLayout类似。看下不同属性对应的不同主轴跟侧轴
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexWrap="wrap"
app:flexDirection="row/row_reverse/column/column_reverse">
<TextView
style="@style/flex_common_style"
android:text="1"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
效果
3,justifyContent
控制主轴方向上的对齐方式
flex_start(默认的)。从开头对齐
flex_end。从结尾对齐
center。居中
space_between。两端对齐
space_around。环绕
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexWrap="wrap"
app:justifyContent="flex_start/center/flex_end/space_between/space_around">
<TextView
style="@style/flex_common_style"
android:text="1"/>
<TextView
style="@style/flex_common_style"
android:text="2"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
效果如下
4,alignItems
控制侧轴的对齐方式
stretch (默认的)。 拉伸
flex_start。从开始位置对齐
flex_end。从结束位置对齐
center。居中
baseline。基线对齐
代码
//不同的只是alignItems的几个属性
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:flexWrap="wrap"
app:alignItems="baseline">
<TextView
style="@style/flex_common_style"
android:text="1"/>
<TextView
style="@style/flex_common_style"
android:text="2"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
效果图对比
5,alignContent
控制侧轴内每一个lines(行或列,看主轴方向)的对齐方式。
stretch (默认的)。拉伸
flex_start。从开始位置对齐
flex_end。从结束位置对齐
center。居中
space_between。两端对齐
space_around。环绕
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:alignContent="stretch">
<TextView
style="@style/flex_common_style"
android:text="1"/>
<TextView
style="@style/flex_common_style"
android:text="2"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
效果图对比
6,alignItem与alignContent区别
这两个属性都是操作侧轴对齐方式的。alignContent适用于多行,它是把所有的item当作一个整体来操作,alignItem把item按flex Lines(行或列,看主轴方向)来一组一组的操作。
看下图的单行和多行对比,一目了然。
7,Divider
- showDividerHorizontal
设置横向分割线位置,取值(none | beginning | middle | end ),可以设置一个或多个。 - dividerDrawableHorizontal
属性是drawable。设置横向多行(或者方向是column或column_reverse)之间的分割线drawable。 - showDividerVertical
同横向的一样,不过,方向是纵向。 - dividerDrawableVertical
属性是drawable。设置纵向多列(或者方向是row或row_reverse)之间的分割线drawable. - showDivider
统一设置横向和纵向的分割线位置,取值(none | beginning | middle | end ),可以设置一个或多个。 - dividerDrawable
属性是drawable。设置横向和纵向之间的分割线drawable.
注意:如果你使用了其他的属性(比如:justifyContent=”space_around” 或alignContent=”space_between”等),让item或者flex lines(行或列)之间存在空间,你可能会看到意想不到的事情。请避免同时使用。
代码
//shape_flex_divide.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size
android:width="4dp"
android:height="8dp" />
<solid android:color="#099aff" />
</shape>
//dividerDrawable设置
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:dividerDrawable="@drawable/shape_flex_divider"
app:showDivider="beginning|middle|end"
app:alignItems="center">
···
</com.google.android.flexbox.FlexboxLayout>
测试效果
FlexboxLayout 内部Item的属性
1,layout_order
这个属性可以改变 item 的排列顺序。默认,子view会按照xml里面写的顺序显示。
默认值是1。属性值越小,排序越靠前。
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:alignContent="center">
<TextView
style="@style/flex_common_style"
app:layout_order="2"
android:text="1"/>
···
<TextView
style="@style/flex_common_style"
app:layout_order="-1"
android:text="12"/>
<TextView
style="@style/flex_common_style"
app:layout_order="0"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
测试效果
2,layout_flexGrow
该属性类似与Linearlayout 的权重weight。
如果一个flex item 有一个正的layout_flexGrow 值,这个item将占据这个flex line(一行或一列)的剩余的空间。
如果在同一个flex line(一行或一列)有多个flex item有正的layout_flexGrow 值,它们将根据layout_flexGrow 值的比例来占据剩余的空间。
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:alignContent="center">
<TextView
style="@style/flex_common_style"
android:text="1"/>
<TextView
style="@style/flex_common_style"
app:layout_flexGrow="10"
android:text="2"/>
···
<TextView
style="@style/flex_common_style"
android:text="13"/>
</com.google.android.flexbox.FlexboxLayout>
测试效果
2,layout_flexShrink
此属性确定,相对于包含在同一个flex line(一行或一列)中的其他flex items的其余部分分配了可用空间空间,此子节点将收缩多少
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="nowrap"
app:alignItems="center">
<TextView
style="@style/flex_common_style"
app:layout_flexShrink="0"
android:text="1"/>
<TextView
style="@style/flex_common_style"
app:layout_flexShrink="2"
android:text="2"/>
<TextView
style="@style/flex_common_style"
app:layout_flexShrink="4"
android:text="3"/>
<TextView
style="@style/flex_common_style"
android:text="4"/>
<TextView
style="@style/flex_common_style"
android:text="5"/>
</com.google.android.flexbox.FlexboxLayout>
效果图
4,layout_alignSelf
这个属性是属于侧轴的对齐方式。如果是在相同方向的对齐方式,这个属性可以使用父view的alignItems 来确定。但是,如果items的这个属性默认的,这个view的对齐方式将会覆盖父view的。
auto (默认的)
flex_start。从开始对齐
flex_end。从结束位置对齐
center。居中
baseline。基线对齐
stretch。拉伸
5,layout_flexBasisPercent (百分比)
初始化 flex 的item长度是相对与父view的百分比格式。
这个属性只有在父布局的长度确定时(MeasureSpec mode 是 MeasureSpec.EXACTLY),才有用。
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:alignItems="center">
<TextView
style="@style/flex_common_style"
app:layout_flexBasisPercent="90%"
android:layout_margin="0dp"
android:text="90%"/>
<TextView
style="@style/flex_common_style"
android:layout_margin="0dp"
android:background="#f00"
app:layout_flexBasisPercent="10%"
android:text="10%"/>
</com.google.android.flexbox.FlexboxLayout>
测试效果
6,layout_minWidth / layout_minHeight (dimension)
这个属性加强了 FlexboxLayout的子类的最小尺寸的限制。这个view不管layout_flexShrink属性如何,它不会比这些属性的值小。
7,layout_maxWidth / layout_maxHeight (dimension)
这个属性加强了 FlexboxLayout的子类的最大尺寸的限制。这个view不管layout_flexGrow 属性如何,不会扩展到比这个属性更大的值。
8,layout_wrapBefore (boolean)
该属性默认是false,如果item设置了该属性为true.这个item就会在flex line(一行或一列)的第一个显示。如果item不是处在第一个的位置上,就会换行并在第一个显示。
代码
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flex_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
app:flexWrap="wrap"
app:alignItems="center">
···
<TextView
style="@style/flex_common_style"
app:layout_wrapBefore="true"
android:background="#00f"
android:text="3"/>
<TextView
style="@style/flex_common_style"
app:layout_wrapBefore="true"
android:background="#00f"
android:text="4"/>
···
</com.google.android.flexbox.FlexboxLayout>
效果图
项目地址:
https://github.com/google/flexbox-layout