github地址(欢迎下载完整Demo)
https://github.com/zhouxu88/FlexboxLayout
效果图
简介:
大家都知道,在以往如果我们想要实现上面这种流式布局,只能去自定义View,继承ViewGroup来做,还是比较复杂的。但是,去年 Google I/O 上开源了一个新的布局控件FlexboxLayout,他的作用就是实现这种流式布局的效果,以后再也不用去自定义了。个人见解,能用官方的就尽量用官方的。
使用详解:
FlexboxLayout项目官方地址 https://github.com/google/flexbox-layout
1、在app的build.gradle中,添加如下依赖
dependencies {
compile 'com.google.android:flexbox:0.3.0'
}
2、按照文档,在xml中可以直接这样使用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.zx.flexboxlayout.MainActivity">
<!--
justifyContent:沿主轴的对齐方向
alignContent:沿副轴的对齐方向
-->
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexboxLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:justifyContent="flex_start"
app:alignContent="flex_start"
app:flexDirection="row"
app:flexWrap="wrap">
<TextView
style="@style/tv_style"
android:text="1、你好" />
<TextView
android:id="@+id/textview2"
style="@style/tv_style"
android:text="2、那就需要加班vyy呵呵哈哈哈或或或" />
<TextView
android:id="@+id/textview3"
style="@style/tv_style"
android:text="3、那就需要加班vyy呵呵或或" />
<TextView
style="@style/tv_style"
android:text="4、行不行啊" />
<TextView
style="@style/tv_style"
android:text="5、你妹啊" />
</com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>
效果图,就是上面的那样,我们以前自定义view实现的流式布局的效果都能实现,可能会有细心的老铁会发现在FlexboxLayout 里面会有几个特殊的属性,没见过,别急,笔者这就把其中比较关键的几个属性和大伙儿讲讲。
3.父容器FlexboxLayout 的属性简介
flexWrap 控制子元素是否换行,以及子元素排列的方向,它有3种取值
nowrap (default) 默认:不换行
wrap 自动换行
wrap_reverse 表示副轴反转,也就是说如果你的子元素的方向是从左往右排列,并且自动换行的,那么此时,水平方向为你的主轴,竖直方向为你的副轴,效果就是,子元素从下往上,从左往右排列。flexDirection 表示子元素的排列方向,元素的排列方向为主轴的方向,该属性有四种取值,不同取值对应不同的主副轴,看下面一张图:
row (default) :默认是横向从左往右排列
row_reverse 横向倒置排列,从右往左
column 竖向从上往下排列
column_reverse 竖向倒置排列,从小往上
justifyContent 表示控件沿主轴对齐方向,它有5个取值
flex_start (default) 默认:左对齐
flex_end 主轴居右对齐
center 主轴居中对齐
space_between 两端对齐,子元素之间的间隔相等,但是两端的子元素分别和左右两边的间距为0
space_around 子元素两端的距离相等,所有子元素两端的距离都相相等alignContent 表示控件在副轴上的对齐方向(针对多行元素),有5个值
stretch (default) 默认值为stretch,表示占满整个副轴,当然,前提需要 把FlexboxLayout的高度改为match_parent才有效果,如果子元素不是很多,系统会自动放大子元素的高度以使之填满父容器。
flex_start 与副轴起点对齐
flex_end 与副轴终点对齐
center
space_between
space_around 同上alignItems 也是描述元素在副轴上的对齐方向(针对单行),属性含义和上文基本一致,只是多了一个baseline,表示基线对齐,其余属性不赘述。
4.子元素属性简介
1.)app:layout_order="2"
这个表示子元素的优先级,默认值为1,数值越大越靠后显示。
2.) app:layout_flexGrow="2"
这个和LinearLayout的权重属性是一样的,表示该子元素所占权重的比例
3.) app:layout_flexShrink="2"
表示空间不足时子控件的缩放比例,0表示不缩放,举个例子:
<com.google.android.flexbox.FlexboxLayout
android:layout_width="300dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="300dp"
android:layout_height="30dp"
app:layout_flexShrink="2"
android:background="@color/black"/>
<TextView
app:layout_flexShrink="1"
android:layout_width="100dp"
android:layout_height="30dp"
android:background="@color/black"/>
</com.google.android.flexbox.FlexboxLayout>
父容器总宽度为300dp,结果两个子元素加起来就400,超过了100dp,总共需要缩小100dp,根据flexShrink属性,第一个TextView缩小100的三分之二,第二个TextView缩小100的三分之一。
它的属性和用法还有很多,请自行前往官网查看
flexbox-layout的使用
差点忘了,一般,我们的子View都是Java代码动态生成的,那代码显示又是怎么弄的呢?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.zx.flexboxlayout.MainActivity">
<!--
justifyContent:沿主轴的对齐方向
alignContent:沿副轴的对齐方向
-->
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexboxLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:justifyContent="flex_start"
app:alignContent="flex_start"
app:flexDirection="row"
app:flexWrap="wrap"/>
</RelativeLayout>
Activity
public class MainActivity extends AppCompatActivity {
String[] tags = {"婚姻育儿", "散文", "设计", "上班这点事儿", "影视天堂", "大学生活", "美人说", "运动和健身", "工具癖", "生活家", "程序员", "想法", "短篇小说", "美食", "教育", "心理", "奇思妙想", "美食", "摄影"};
private FlexboxLayout flexboxLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
flexboxLayout = (FlexboxLayout) findViewById(R.id.flexboxLayout);
//动态添加子View
for (int i = 0; i < tags.length; i++) {
flexboxLayout.addView(getFlexboxLayoutItemView(i));
}
}
//获取FlexboxLayout的子View
private View getFlexboxLayoutItemView(int position) {
View view = getLayoutInflater().inflate(R.layout.item_flex_box_layout, null, false);
TextView itemTv = (TextView) view.findViewById(R.id.item_tv);
itemTv.setText(tags[position]);
return view;
}
}