之前看到一個(gè)很炫酷的布局:FlexboxLayout鲸鹦,可以很方便地實(shí)現(xiàn)瀑布流的效果憋沿。今天正好用到項(xiàng)目中,對(duì)FlexboxLayout進(jìn)行一個(gè)簡(jiǎn)單的學(xué)習(xí)季稳。
一擅这、效果圖
先來(lái)看一波效果圖。
很熟悉景鼠,對(duì)不對(duì)仲翎?就是簡(jiǎn)書(shū)的定制熱門(mén)頁(yè)面。通過(guò)今天的學(xué)習(xí)铛漓,利用FlexboxLayout+RecyclerView就可以實(shí)現(xiàn)溯香。
下面是自己實(shí)現(xiàn)的效果圖:
像上述的應(yīng)用場(chǎng)景,會(huì)經(jīng)常在一些APP中看到浓恶。那么就學(xué)起來(lái)吧玫坛,看看是怎么實(shí)現(xiàn)的。
二包晰、FlexboxLayout簡(jiǎn)介
FlexboxLayout is a library project which brings the similar capabilities of CSS Flexible Box Layout Module to Android.
FlexboxLayout是一個(gè)Android平臺(tái)上與CSS的 Flexible box 布局模塊 有相似功能的庫(kù)湿镀。Flexbox 是CSS 的一種布局方案炕吸,可以簡(jiǎn)單、快捷的實(shí)現(xiàn)復(fù)雜布局勉痴。FlexboxLayout可以理解成一個(gè)高級(jí)版的LinearLayout赫模,因?yàn)閮蓚€(gè)布局都把子view按順序排列。兩者之間最大的差別在于FlexboxLayout具有換行的特性蒸矛。
FlexboxLayout是Google開(kāi)源的一款強(qiáng)大的布局瀑罗,如果英文好可以直接看其屬性信息的詳細(xì)介紹,Github地址雏掠。
當(dāng)然斩祭,也可以看一些翻譯過(guò)來(lái)的對(duì)FlexboxLayout的介紹,比如:Android可伸縮布局-FlexboxLayout(支持RecyclerView集成),介紹的很清楚磁玉。
三停忿、FlexboxLayout重要屬性
下面僅介紹幾中常用的FlexboxLayout屬性驾讲。
flexDirection:
flexDirection屬性決定了主軸的方向蚊伞,即FlexboxLayout里子Item的排列方向,有以下四種取值:
row (default): 默認(rèn)值吮铭,主軸為水平方向时迫,從左到右。
row_reverse:主軸為水平方向谓晌,起點(diǎn)在有端掠拳,從右到左。
column:主軸為豎直方向纸肉,起點(diǎn)在上端溺欧,從上到下。
column_reverse:主軸為豎直方向柏肪,起點(diǎn)在下端姐刁,從下往上。
flexWrap
flexWrap 這個(gè)屬性決定Flex 容器是單行還是多行烦味,并且決定副軸(與主軸垂直的軸)的方向聂使。可能有以下3個(gè)值:
noWrap: 不換行,一行顯示完子元素谬俄。
wrap: 按正常方向換行柏靶。
wrap_reverse: 按反方向換行。
justifyContent
justifyContent 屬性控制元素主軸方向上的對(duì)齊方式溃论,有以下5種取值:
flex_start (default): 默認(rèn)值屎蜓,左對(duì)齊
flex_end: 右對(duì)齊
center: 居中對(duì)齊
space_between: 兩端對(duì)齊,中間間隔相同
space_around: 每個(gè)元素到兩側(cè)的距離相等钥勋。
alignItems
alignItems 屬性控制元素在副軸方向的對(duì)齊方式炬转,有以下5種取值:
stretch (default) :默認(rèn)值控汉,如果item沒(méi)有設(shè)置高度,則充滿容器高度返吻。
flex_start:頂端對(duì)齊
flex_end:底部對(duì)齊
center:居中對(duì)齊
baseline:第一行內(nèi)容的的基線對(duì)齊
alignContent
alignContent 屬性控制多根軸線的對(duì)齊方式(也就是控制多行姑子,如果子元素只有一行,則不起作用)测僵,可能有以下6種取值:
stretch (default): 默認(rèn)值街佑,充滿交叉軸的高度(測(cè)試發(fā)現(xiàn),需要alignItems 的值也為stretch 才有效)捍靠。
flex_start: 與交叉軸起點(diǎn)對(duì)齊沐旨。
flex_end: 與交叉軸終點(diǎn)對(duì)齊。
center: 與交叉軸居中對(duì)齊榨婆。
space_between: 交叉軸兩端對(duì)齊磁携,中間間隔相等。
space_around: 到交叉軸兩端的距離相等良风。
FleboxLayout子元素支持的重要屬性
以下介紹幾個(gè)子元素支持的重要屬性
layout_flexGrow(float)
layout_flexGrow 子元素的放大比例谊迄, 決定如何分配剩余空間(如果存在剩余空間的話),默認(rèn)值為0,不會(huì)分配剩余空間烟央,如果有一個(gè)item的 layout_flexGrow 是一個(gè)正值统诺,那么會(huì)將全部剩余空間分配給這個(gè)Item,如果有多個(gè)Item這個(gè)屬性都為正值,那么剩余空間的分配按照l(shuí)ayout_flexGrow定義的比例(有點(diǎn)像LinearLayout的layout_weight屬性)疑俭。
layout_flexBasisPercent (fraction)
layout_flexBasisPercent的值為一個(gè)百分比粮呢,表示設(shè)置子元素的長(zhǎng)度為它父容器長(zhǎng)度的百分比,如果設(shè)置了這個(gè)值钞艇,那么通過(guò)這個(gè)屬性計(jì)算的值將會(huì)覆蓋layout_width或者layout_height的值啄寡。但是需要注意,這個(gè)值只有設(shè)置了父容器的長(zhǎng)度時(shí)才有效(也就是MeasureSpec mode 是 MeasureSpec.EXACTLY)哩照。默認(rèn)值時(shí)-1挺物。
FlexboxLayout還有需要其他的擁有強(qiáng)大功能的屬性,如有需要葡秒,可通過(guò)上面兩篇文章進(jìn)行了解姻乓。
四、FlexboxLayout使用
1眯牧、添加依賴
compile 'com.google.android:flexbox:0.2.5'
2蹋岩、具體代碼
第一種方式:
布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/flexbox_layout"
app:flexWrap="wrap"
app:alignItems="center"
app:alignContent="flex_start"
app:flexDirection="row"
app:justifyContent="flex_start"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
app:layout_alignSelf="flex_start"
android:text="程序員"
android:gravity="center"
android:textColor="@color/text_color"
/>
..............................................................................
</com.google.android.flexbox.FlexboxLayout>
可以通過(guò)向FlexboxLayout添加多個(gè)子控件來(lái)實(shí)現(xiàn)瀑布流的效果。也可以在代碼中動(dòng)態(tài)添加子控件來(lái)實(shí)現(xiàn)同種效果学少。不過(guò)這種情況不適合子View過(guò)多的場(chǎng)景剪个,如果子View過(guò)多,建議使用FlexboxLayout+RecyclerView的方式版确,下面具體介紹扣囊。
第二種方式:
首先要換掉原來(lái)的依賴乎折,依賴最新的alpha版本,如下:
compile 'com.google.android:flexbox:0.3.0-alpha2'
布局文件
<?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:fitsSystemWindows="false"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/background_material_light_1"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_wrong"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:src="@drawable/favor_wrong"/>
<ImageView
android:id="@+id/iv_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:paddingRight="10dp"
android:src="@drawable/favor_right"/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_favor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
主布局中放入RecyclerView侵歇。
添加內(nèi)容
mAdapter = new FavorMovieAdapter(list,mContext,mSelectList);
FlexboxLayoutManager manager = new FlexboxLayoutManager();
//設(shè)置主軸排列方式
manager.setFlexDirection(FlexDirection.ROW);
//設(shè)置是否換行
manager.setFlexWrap(FlexWrap.WRAP);
mRvFavor.setLayoutManager(manager);
mRvFavor.setItemAnimator(new DefaultItemAnimator());
mRvFavor.setAdapter(mAdapter);
通過(guò)FlexboxLayoutManager 作為一個(gè)LayoutManager(FlexboxlayoutManager) 用在RecyclerView里面骂澄,實(shí)現(xiàn)FlexboxLayout的強(qiáng)大功能。
在Adapter設(shè)置子元素屬性
填充每一行的剩余空間
ViewGroup.LayoutParams params = holder.mTitle.getLayoutParams();
if (params instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) holder.mTitle.getLayoutParams();
flexboxLp.setFlexGrow(1.0f);
}
五惕虑、總結(jié)
FlexboxLayout+RecyclerView可以實(shí)現(xiàn)瀑布流的效果坟冲,不需要指定列數(shù),可以實(shí)現(xiàn)自動(dòng)換行溃蔫,而且FlexboxLayout具有的各種屬性健提,使得瀑布流的形式更加靈活多變。以上只是一些簡(jiǎn)單的使用伟叛。