项目需要实现一个瀑布流的功能,正好了解到FlexboxLayout布局,便准备用FlexboxLayout来实现
一、什么是FlexboxLayout
看一下Github对这个库的介绍:FlexboxLayout is a library project which brings the similar capabilities ofCSS Flexible Box Layout Moduleto Android. 意思是:FlexboxLayout是一个Android平台上与CSS的 Flexible box 布局模块 有相似功能的库。Flexbox 是CSS 的一种布局方案,可以简单、快捷的实现复杂布局。FlexboxLayout可以理解成一个高级版的LinearLayout,因为两个布局都把子view按顺序排列。两者之间最大的差别在于FlexboxLayout具有换行的特性。
二、 FlexboxLayout效果图
三、FlexboxLayout重要属性
1.flexDirection:
flexDirection属性决定了主轴的方向,即FlexboxLayout里子Item的排列方向,有以下四种取值:
row (default): 默认值,主轴为水平方向,从左到右。
row_reverse:主轴为水平方向,起点在有端,从右到左。
column:主轴为竖直方向,起点在上端,从上到下。
column_reverse:主轴为竖直方向,起点在下端,从下往上。
2.flexWrap
flexWrap 这个属性决定Flex 容器是单行还是多行,并且决定副轴(与主轴垂直的轴)的方向。可能有以下3个值:
noWrap: 不换行,一行显示完子元素。
wrap: 按正常方向换行。
wrap_reverse: 按反方向换行。
3.justifyContent
justifyContent 属性控制元素主轴方向上的对齐方式,有以下5种取值:
flex_start (default): 默认值,左对齐
flex_end: 右对齐
center: 居中对齐
space_between: 两端对齐,中间间隔相同
space_around: 每个元素到两侧的距离相等。
4.alignItems
alignItems 属性控制元素在副轴方向的对齐方式,有以下5种取值:
stretch (default) :默认值,如果item没有设置高度,则充满容器高度。
flex_start:顶端对齐
flex_end:底部对齐
center:居中对齐
baseline:第一行内容的的基线对齐
5.alignContent
alignContent 属性控制多根轴线的对齐方式(也就是控制多行,如果子元素只有一行,则不起作用),可能有以下6种取值:
stretch (default): 默认值,充满交叉轴的高度(测试发现,需要alignItems 的值也为stretch 才有效)。
flex_start: 与交叉轴起点对齐。
flex_end: 与交叉轴终点对齐。
center: 与交叉轴居中对齐。
space_between: 交叉轴两端对齐,中间间隔相等。
space_around: 到交叉轴两端的距离相等。
以下介绍几个子元素支持的重要属性
layout_flexGrow(float)
layout_flexGrow 子元素的放大比例, 决定如何分配剩余空间(如果存在剩余空间的话),默认值为0,不会分配剩余空间,如果有一个item的 layout_flexGrow 是一个正值,那么会将全部剩余空间分配给这个Item,如果有多个Item这个属性都为正值,那么剩余空间的分配按照layout_flexGrow定义的比例(有点像LinearLayout的layout_weight属性)。
layout_flexBasisPercent (fraction)
layout_flexBasisPercent的值为一个百分比,表示设置子元素的长度为它父容器长度的百分比,如果设置了这个值,那么通过这个属性计算的值将会覆盖layout_width或者layout_height的值。但是需要注意,这个值只有设置了父容器的长度时才有效(也就是MeasureSpec mode 是 MeasureSpec.EXACTLY)。默认值时-1。
四,如何实现
1、添加依赖
compile 'com.google.android:flexbox:1.0.0'
2.布局文件
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/flexbox_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:alignContent="stretch"
app:flexDirection="row"
app:flexWrap="wrap">
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="1"
app:layout_flexGrow="1.0" />
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="2"
app:layout_wrapBefore="true" />
android:id="@+id/text3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="3" />
</com.google.android.flexbox.FlexboxLayout>
也可以通过代码设置排列方向等:
flexboxLayout.setFlexDirection(FlexDirection.ROW);
View view = flexboxLayout.getChildAt(0);
FlexboxLayout.LayoutParams lp = (FlexboxLayout.LayoutParams) view.getLayoutParams();
lp.order = -1;
lp.flexGrow = 2;
view.setLayoutParams(lp);```
## 五、 RecyclerView 的支持
#### 1.在布局文件中放入recyclerView就行了
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/test_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
2.设置recylerView的LayoutManager
RecyclerViewmRecyclerView=(RecyclerView)findViewById(R.id.test_recyclerView);FlexboxLayoutManagerlayoutManager=newFlexboxLayoutManager();layoutManager.setFlexWrap(FlexWrap.WRAP);//设置是否换行 layoutManager.setFlexDirection(FlexDirection.ROW);// 设置主轴排列方式layoutManager.setAlignItems(AlignItems.STRETCH);layoutManager.setJustifyContent(JustifyContent.FLEX_START);mRecyclerView.setLayoutManager(layoutManager);
3.Adapter 中绑定 View 的时候,设置子元素的属性
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
flexboxLp.setFlexGrow(1.0f);
flexboxLp.setAlignSelf(AlignSelf.FLEX_END);
}