github地址(歡迎下載完整Demo)
https://github.com/zhouxu88/FlexboxLayout
效果圖


簡介:
大家都知道,在以往如果我們想要實現(xiàn)上面這種流式布局,只能去自定義View,繼承ViewGroup來做,還是比較復(fù)雜的。但是,去年 Google I/O 上開源了一個新的布局控件FlexboxLayout,他的作用就是實現(xiàn)這種流式布局的效果,以后再也不用去自定義了。個人見解,能用官方的就盡量用官方的。
使用詳解:
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實現(xiàn)的流式布局的效果都能實現(xiàn),可能會有細心的老鐵會發(fā)現(xiàn)在FlexboxLayout 里面會有幾個特殊的屬性,沒見過,別急,筆者這就把其中比較關(guān)鍵的幾個屬性和大伙兒講講。
3.父容器FlexboxLayout 的屬性簡介
flexWrap 控制子元素是否換行,以及子元素排列的方向,它有3種取值
nowrap (default) 默認(rèn):不換行
wrap 自動換行
wrap_reverse 表示副軸反轉(zhuǎn),也就是說如果你的子元素的方向是從左往右排列,并且自動換行的,那么此時,水平方向為你的主軸,豎直方向為你的副軸,效果就是,子元素從下往上,從左往右排列。flexDirection 表示子元素的排列方向,元素的排列方向為主軸的方向,該屬性有四種取值,不同取值對應(yīng)不同的主副軸,看下面一張圖:

row (default) :默認(rèn)是橫向從左往右排列
row_reverse 橫向倒置排列,從右往左
column 豎向從上往下排列
column_reverse 豎向倒置排列,從小往上
justifyContent 表示控件沿主軸對齊方向,它有5個取值
flex_start (default) 默認(rèn):左對齊
flex_end 主軸居右對齊
center 主軸居中對齊
space_between 兩端對齊,子元素之間的間隔相等,但是兩端的子元素分別和左右兩邊的間距為0
space_around 子元素兩端的距離相等,所有子元素兩端的距離都相相等alignContent 表示控件在副軸上的對齊方向(針對多行元素),有5個值
stretch (default) 默認(rèn)值為stretch,表示占滿整個副軸,當(dāng)然,前提需要 把FlexboxLayout的高度改為match_parent才有效果,如果子元素不是很多,系統(tǒng)會自動放大子元素的高度以使之填滿父容器。
flex_start 與副軸起點對齊
flex_end 與副軸終點對齊
center
space_between
space_around 同上alignItems 也是描述元素在副軸上的對齊方向(針對單行),屬性含義和上文基本一致,只是多了一個baseline,表示基線對齊,其余屬性不贅述。
4.子元素屬性簡介
1.)app:layout_order="2"
這個表示子元素的優(yōu)先級,默認(rèn)值為1,數(shù)值越大越靠后顯示。
2.) app:layout_flexGrow="2"
這個和LinearLayout的權(quán)重屬性是一樣的,表示該子元素所占權(quán)重的比例
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,結(jié)果兩個子元素加起來就400,超過了100dp,總共需要縮小100dp,根據(jù)flexShrink屬性,第一個TextView縮小100的三分之二,第二個TextView縮小100的三分之一。
它的屬性和用法還有很多,請自行前往官網(wǎng)查看
flexbox-layout的使用
差點忘了,一般,我們的子View都是Java代碼動態(tài)生成的,那代碼顯示又是怎么弄的呢?
<?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 = {"婚姻育兒", "散文", "設(shè)計", "上班這點事兒", "影視天堂", "大學(xué)生活", "美人說", "運動和健身", "工具癖", "生活家", "程序員", "想法", "短篇小說", "美食", "教育", "心理", "奇思妙想", "美食", "攝影"};
private FlexboxLayout flexboxLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
flexboxLayout = (FlexboxLayout) findViewById(R.id.flexboxLayout);
//動態(tài)添加子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;
}
}