1. 程式人生 > >Android開發之玩轉FlexboxLayout佈局(可用於普通控制元件實現流式佈局,也可結合RecycleView實現流式佈局)

Android開發之玩轉FlexboxLayout佈局(可用於普通控制元件實現流式佈局,也可結合RecycleView實現流式佈局)

在這之前,我曾認真的研究過鴻洋大神的Android 自定義ViewGroup 實戰篇 -> 實現FlowLayout,按照大神的思路寫出了一個流式佈局,所有的東西都是難者不會會者不難,當自己能自定義流式佈局的時候就會覺得這東西原來很簡單了。如果各位小夥伴也看過那篇文章的話,應該知道自定義流式佈局還是非常麻煩的,不過Google今年開源了新的容器,就是這個FlexboxLayout,如果你玩過前端開發或者玩過RN,就會覺得這個FlexboxLayout真是簡單,OK,那我們今天就來看看這個FlexboxLayout的使用吧!先來看看顯示效果:

OK,我們來看看這個東東要怎麼實現吧!

1.引入專案

使用之前當然是先引入了,Google在GitHub上開源了這個控制元件,地址如下:

OK,在專案中引入方式如下:

在module的gradle檔案中新增如下一行:

[java] view plain copy  print?
  1. compile 'com.google.android:flexbox:0.2.3'

版本號為本文釋出時的最新版本號。

引入之後就可以使用了。

2.基本用法

根據GitHub上給我們的Demo,可以看到FlexboxLayout在使用的過程中只需要用容器將我們的子控制元件包裹起來就行了,主佈局檔案如下:

[java]
 view plain copy  print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout  
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     xmlns:app="http://schemas.android.com/apk/res-auto"
  5.     xmlns:tools="http://schemas.android.com/tools"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     tools:context="org.lenve.flexbox.MainActivity">  
  9.     <com.google.android.flexbox.FlexboxLayout  
  10.         android:layout_width="match_parent"
  11.         android:layout_height="wrap_content"
  12.         app:flexWrap="wrap">  
  13.         <TextView  
  14.             android:layout_width="wrap_content"
  15.             android:layout_height="wrap_content"
  16.             android:layout_margin="8dp"
  17.             android:background="@drawable/tv_bg"
  18.             android:padding="8dp"
  19.             android:text="1.水陸草木之花"/>  
  20.         <TextView  
  21.             android:layout_width="wrap_content"
  22.             android:layout_height="wrap_content"
  23.             android:layout_margin="8dp"
  24.             android:background="@drawable/tv_bg"
  25.             android:padding="8dp"
  26.             android:text="2.可愛者甚蕃"/>  
  27.         <TextView  
  28.             android:layout_width="wrap_content"
  29.             android:layout_height="wrap_content"
  30.             android:layout_margin="8dp"
  31.             android:background="@drawable/tv_bg"
  32.             android:padding="8dp"
  33.             android:text="3.晉陶淵明獨愛菊"/>  
  34.         <TextView  
  35.             android:layout_width="wrap_content"
  36.             android:layout_height="wrap_content"
  37.             android:layout_margin="8dp"
  38.             android:background="@drawable/tv_bg"
  39.             android:padding="8dp"
  40.             android:text="4.自李唐來"/>  
  41.         <TextView  
  42.             android:layout_width="wrap_content"
  43.             android:layout_height="wrap_content"
  44.             android:layout_margin="8dp"
  45.             android:background="@drawable/tv_bg"
  46.             android:padding="8dp"
  47.             android:text="5.世人甚愛牡丹"/>  
  48.         <TextView  
  49.             android:layout_width="wrap_content"
  50.             android:layout_height="wrap_content"
  51.             android:layout_margin="8dp"
  52.             android:background="@drawable/tv_bg"
  53.             android:padding="8dp"
  54.             android:text="6.予獨愛蓮之出淤泥而不染"/>  
  55.         <TextView  
  56.             android:layout_width="wrap_content"
  57.             android:layout_height="wrap_content"
  58.             android:layout_margin="8dp"
  59.             android:background="@drawable/tv_bg"
  60.             android:padding="8dp"
  61.             android:text="7.濯清漣而不妖"/>  
  62.         <TextView  
  63.             android:layout_width="wrap_content"
  64.             android:layout_height="wrap_content"
  65.             android:layout_margin="8dp"
  66.             android:background="@drawable/tv_bg"
  67.             android:padding="8dp"
  68.             android:text="8.中通外直"/>  
  69.         <TextView  
  70.             android:layout_width="wrap_content"
  71.             android:layout_height="wrap_content"
  72.             android:layout_margin="8dp"
  73.             android:background="@drawable/tv_bg"
  74.             android:padding="8dp"
  75.             android:text="9.不蔓不枝"/>  
  76.         <TextView  
  77.             android:layout_width="wrap_content"
  78.             android:layout_height="wrap_content"
  79.             android:layout_margin="8dp"
  80.             android:background="@drawable/tv_bg"
  81.             android:padding="8dp"
  82.             android:text="10.香遠益清"/>  
  83.         <TextView  
  84.             android:layout_width="wrap_content"
  85.             android:layout_height="wrap_content"
  86.             android:layout_margin="8dp"
  87.             android:background="@drawable/tv_bg"
  88.             android:padding="8dp"
  89.             android:text="11.亭亭淨植"/>  
  90.     </com.google.android.flexbox.FlexboxLayout>  
  91. </RelativeLayout>  

顯示效果就是我們上文貼出來的圖。

3.父容器屬性簡介

flexWrap    屬性表示換行與否,預設為noWrap,表示不換行,wrap表示自動換行,還有一個wrap_reverse 表示副軸反轉,副軸的含義我們一會來說。

flexDirection  表示子元素的排列方向,元素的排列方向為主軸的方向,該屬性有四種取值,不同取值對應不同的主副軸,看下面一張圖:

預設為row,所以如果我給flexWrap取wrap_reverse屬性,則效果如下:

副軸取反,由於flexDirection預設為row,即副軸為豎直方向,副軸取反,即豎直方向倒著顯示。同理,如果我給flexDirection屬性設定為column,對應主軸方向為豎直向下,這個時候控制元件就會按如下方式來顯示:

其它值我就不一一測試了。

justifyContent 表示控制元件沿主軸對齊方向,有五種取值,預設情況下大家看到控制元件是左對齊(flex_start),另外還有主軸居中對齊(center):

主軸居右對齊(flex_end):

兩端對齊,子元素之間的間隔相等,但是兩端的子元素分別和左右兩邊的間距為0(space_between):

子元素兩端的距離相等,所有子元素兩端的距離都相相等(space_around):

alignContent 表示控制元件在副軸上的對齊方向(針對多行元素),預設值為stretch,表示佔滿整個副軸,因為上文中我把FlexboxLayout的高度設定為包裹內容,所以這個屬性大家可能沒看到效果,這裡我把FlexboxLayout的高度改為match_parent,我們再來看看效果:

程式碼:

[java] view plain copy  print?
  1.   <com.google.android.flexbox.FlexboxLayout  
  2.       android:layout_width="match_parent"
  3.       android:layout_height="match_parent"
  4.       app:alignContent="stretch"
  5.       app:flexWrap="wrap">  
  6. ....  
  7. ....  

效果:

大家看到系統會自動放大子元素的高度以使之填滿父容器。

與副軸起點對齊(flex_start):

程式碼:

[java] view plain copy  print?
  1.     <com.google.android.flexbox.FlexboxLayout  
  2.         android:layout_width="match_parent"
  3.         android:layout_height="match_parent"
  4.         app:alignContent="flex_start"
  5.         app:flexWrap="wrap">  
  6. ....  
  7. ....  

與副軸終點對齊(flex_end):

[java] view plain copy  print?
  1.     <com.google.android.flexbox.FlexboxLayout  
  2.         android:layout_width="match_parent"
  3.         android:layout_height="match_parent"
  4.         app:alignContent="flex_end"
  5.         app:flexWrap="wrap">  
  6. ...  
  7. ...  

還有兩個值,分別是space_around和space_between,意思和上文說的一樣,這裡不再贅述。

alignItems 也是描述元素在副軸上的對齊方向(針對單行),屬性含義和上文基本一致,只是多了一個baseline,表示基線對齊,其餘屬性不贅述。

這裡說的都是父容器的屬性,那麼子元素都有哪些屬性呢?

4.子元素屬性簡介

[java] view plain copy  print?
  1. app:layout_order="2"
這個表示子元素的優先順序,預設值為1,數值越大越靠後顯示。 [java] view plain copy  print?
  1. app:layout_flexGrow="2"

這個類似於權重屬性,來個示例程式碼: [java] view plain