用FlexboxLayout構(gòu)建靈活的布局

在去年的Google I/O大會上碘橘,Google發(fā)布了 ConstraintLayout他使我們能夠使用一個平面的視圖層次來構(gòu)建復(fù)雜的界面布局畜埋。android studio的視圖編輯器也對其實現(xiàn)了完整支持熙掺。

與此同時匪补,Google開源了FlexboxLayout 他與CSS Flexible 布局模塊具有相同的功能佑钾。接下來的例子我們將使用FlexboxLayout實現(xiàn)一些特殊的功能西疤。

你可以把FlexboxLayout理解成一個高級的LinearLayout,他和LinearLayout一樣都是在水平和垂直方向上按順序放置子view,他與LinearLayout最大的不同在于FlexboxLayout 有一個wrapping功能。當(dāng)你增加flexWrap="wrap"屬性后休溶,假如在當(dāng)前方向上沒有足夠的空間可以放置新的子view代赁,他會在新的一行上放置子view。

同一布局適配多種屏幕尺寸

我們想要在水平方向依次放置一些view兽掰,假如有效的空間發(fā)生變化后(不同的手機設(shè)備芭碍、手機方向發(fā)生改變、多窗口模式導(dǎo)致的界面重繪等)我們想要在新的一行繼續(xù)放置上一行沒有空閑空間顯示的view孽尽。

Nexus5X堅屏
Nexus5X橫屏
Pixel C 多窗口模式分隔線在左邊
Pixel C 多窗口模式分隔線在中間
Pixel C 多窗口模式分隔線在右邊

如果你使用傳統(tǒng)的布局方式來實現(xiàn)這個功能,如LinearLayout窖壕、RelativeLayout你需要定義多個 DP-bucket 布局(例如layout-600dp, layout-720dp, layout-1020dp)來處理多屏幕尺寸的問題。但是上邊的對話框只使用了一個FlexboxLayout就實現(xiàn)了這個功能杉女。

這個例子中使用了上邊提到的flexWrap="wrap"屬性

     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:flexwrap="wrap">
     ......```
使用flexwrap="wrap"你將得到下邊的布局效果瞻讽,而不會是像LinearLayout那樣從父布局中溢出
![](http://upload-images.jianshu.io/upload_images/2758471-39b536593cd5f28e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

另一個比較有用的屬性是layout_flexGrow,他被設(shè)置到FlexboxLayout的孩子view上熏挎,這個屬性有點類似于LinearLayout的layout_weight卸夕,不同的地方在于LinearLayout是根據(jù)layout_weight的值來將多余的空間分配給每個子view的高或?qū)挘鳩lexboxLayout是按照layout_flexGrow屬性的值將多余的空間轉(zhuǎn)換為在同一行的子view之間的間隔距離婆瓜。下邊的例子,將layout_flexGrow的值設(shè)為1:

<android.support.design.widget.TextInputLayout
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_flexgrow="1">



![](http://upload-images.jianshu.io/upload_images/2758471-a8d81eaca66aedc7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

你可以從Github上得到完整的[布局文件](https://github.com/google/flexbox-layout/blob/master/app/src/main/res/layout/fragment_flex_item_edit.xml) 

######與RecyclerView結(jié)合使用

FlexboxLayout的另外一個好處是他能與RecyclerView結(jié)合使用贡羔,在最新發(fā)布的alpha版本提供了新的RecyclerView布局管理器FlexboxLayoutManager他繼承自RecyclerView.LayoutManager廉白,你現(xiàn)在可以用這種更加高效利用內(nèi)存的方式在滾動容器里實現(xiàn)Flexbox功能。當(dāng)然你也可以用ScrollView結(jié)合FlexboxLayout來達到在可滾動的容器中實現(xiàn)Flexbox功能乖寒,但是當(dāng)容器中的子view數(shù)量很多的時候?qū)?dǎo)致OutOfMemoryError的發(fā)生猴蹂。事實上有許多可以用FlexboxLayout與RecyclerView結(jié)合使用的場景,比如Google 的Photos app 或新聞app楣嘁。這兩個應(yīng)用都需要顯示大量寬度不同的圖片磅轻。

下邊是一個例子珍逸,每一個顯示在RecyclerView中的圖片都有不同的寬度,我們設(shè)置flexWrap的值到wrap

FlexboxLayoutManager layoutManager = new FlexboxLayoutManager();
layoutManager.setFlexWrap(FlexWrap.WRAP);

然后設(shè)置flexGrow的值(這樣就不用依次給每個item設(shè)置flexGrow值 )

void bindTo(Drawable drawable) {
mImageView.setImageDrawable(drawable);
ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp =
(FlexboxLayoutManager.LayoutParams) mImageView.getLayoutParams();
flexboxLp.setFlexGrow(1.0f);
}
}


效果如下:

![豎屏](http://upload-images.jianshu.io/upload_images/2758471-5ffb80a77f3878de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



![橫屏](http://upload-images.jianshu.io/upload_images/2758471-d96e539cf7148f10.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

可以看到無論是橫屏還是豎屏都能很好的適配聋溜。

本篇文章就結(jié)束了谆膳,如果您有任何問題,歡迎與我聯(lián)系撮躁。如果文中有錯誤的地方也歡迎您指證漱病,我將不勝感激。

如果您想要查看完整的例子代碼請查看:

[Playground 例子app](https://github.com/google/flexbox-layout/tree/dev_recyclerview/demo-playground) - 使用了FlexboxLayout和FlexboxLayoutManager實現(xiàn)
[Cat gallery例子app](https://github.com/google/flexbox-layout/tree/dev_recyclerview/demo-cat-gallery) - 使用FlexboxLayoutManager實現(xiàn)

本文參考自google官方文檔 https://android-developers.googleblog.com/2017/02/build-flexible-layouts-with.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末把曼,一起剝皮案震驚了整個濱河市杨帽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗤军,老刑警劉巖注盈,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異叙赚,居然都是意外死亡老客,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門纠俭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沿量,“玉大人,你說我怎么就攤上這事冤荆∑釉颍” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵钓简,是天一觀的道長乌妒。 經(jīng)常有香客問我,道長外邓,這世上最難降的妖魔是什么撤蚊? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮损话,結(jié)果婚禮上侦啸,老公的妹妹穿的比我還像新娘。我一直安慰自己丧枪,他們只是感情好光涂,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拧烦,像睡著了一般忘闻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上恋博,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天齐佳,我揣著相機與錄音私恬,去河邊找鬼。 笑死炼吴,一個胖子當(dāng)著我的面吹牛本鸣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缺厉,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼永高,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了提针?” 一聲冷哼從身側(cè)響起命爬,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辐脖,沒想到半個月后饲宛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡嗜价,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年艇抠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片久锥。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡家淤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瑟由,到底是詐尸還是另有隱情絮重,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布歹苦,位于F島的核電站青伤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏殴瘦。R本人自食惡果不足惜狠角,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚪腋。 院中可真熱鬧丰歌,春花似錦、人聲如沸屉凯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽神得。三九已至,卻和暖如春偷仿,著一層夾襖步出監(jiān)牢的瞬間哩簿,已是汗流浹背宵蕉。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留节榜,地道東北人羡玛。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像宗苍,于是被迫代替她去往敵國和親稼稿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容