Android FlexboxLayout 佈局詳解

FlexboxLayout16Google I/O 上開源的一個佈局控件,使得 Android 裏的 CSS Flexible Layout 模塊也能擁有一樣強大的功能。同時還發布了強大的ConstraintLayout,感興趣的同窗能夠去看看 Android ConstraintLayout 詳解。FlexboxLayout 能夠理解爲高級的 LinearLayout ,由於這兩個佈局都將其子視圖按序排列。兩者之間的重要差別在於 FlexboxLayout 具備 換行 的特性。同時 FlexboxLayout 還爲 RecycleView 提供了管理器 FlexboxLayoutManager,使得 FlexboxLayout 更增強大了。android

FlexboxLayout 項目開源地址:flexbox-layoutgit

本篇文章demo源碼地址:FlexboxLayoutDemogithub

導入依賴

dependencies {
    //FlexboxLayout
    implementation 'com.google.android:flexbox:1.0.0'
}
複製代碼

注意:從1.1.0開始,這個庫將與AndroidX一塊兒使用。若是您使用1.1.0或以上版本,請遷移到AndroidX。 若是您尚未遷移到AndroidX,請使用1.0.0。bash

示例

XML佈局文件app

<com.google.android.flexbox.FlexboxLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/flexbox_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview1"
        android:layout_width="120dp"
        android:layout_height="20dp"
        android:layout_margin="2dp"
        android:background="#43eeff"
        android:gravity="center"
        android:text="1"/>

    <TextView
        android:id="@+id/textview2"
        android:layout_width="120dp"
        android:layout_height="60dp"
        android:layout_margin="2dp"
        android:background="#ef3344"
        android:gravity="center"
        android:text="2"/>

    <TextView
        android:id="@+id/textview3"
        android:layout_width="120dp"
        android:layout_height="90dp"
        android:layout_margin="2dp"
        android:background="#ee998f"
        android:gravity="center"
        android:text="3"/>

    <TextView
        android:id="@+id/textview4"
        android:layout_width="120dp"
        android:layout_height="100dp"
        android:layout_margin="2dp"
        android:background="#eeff22"
        android:gravity="center"
        android:text="4"/>

    <TextView
        android:id="@+id/textview5"
        android:layout_width="120dp"
        android:layout_height="80dp"
        android:layout_margin="2dp"
        android:background="#3322ff"
        android:gravity="center"
        android:text="5"/>

</com.google.android.flexbox.FlexboxLayout>
複製代碼

運行後的效果以下圖:ide

咱們能夠看到並無換行,和咱們使用 LinearLayout 並無區別,接下來咱們看下 FlexboxLayout 的一些經常使用屬性。工具

FlexboxLayout 經常使用屬性

flexDirection

flexDirection 屬性決定主軸項目排列方向。相似 LinearLayoutverticalhorizontal,可是 FlexboxLayout 更增強大,不只支持橫向和縱向還能夠設置不一樣的排列的起點。佈局

  • row(默認值):主軸爲水平方向,起點在左端。
  • row_reverse:主軸爲水平方向,起點在右端。
  • column:主軸爲垂直方向,起點在上沿。
  • column_reverse:主軸爲垂直方向,起點在下沿。

下面咱們在xml中添加 flexDirection 屬性,並設置起點在下端:學習

app:flexDirection="column_reverse"
複製代碼

運行後的效果以下圖:flex

能夠看到項目是從底部開始由下而上排列的。

flexWrap

默認 FlexboxLayoutLinearLayout 同樣是不帶換行屬性的,可是 flexWrap 屬性能夠支持換行排列。這就是 FlexboxLayout 方便的地方了。換行方式有兩種,一種是按項目排列方向換行,一種是反方向換行

  • nowrap (默認):不換行。

  • wrap:按正常方向換行。

  • wrap_reverse:按反方向換行。

下面咱們在xml中添加 flexWrap 屬性,按照正常方向換行:

app:flexWrap="wrap"
複製代碼

運行後的效果以下圖:

justifyContent

justifyContent 屬性定義了項目在主軸上的對齊方式。

  • flex_start(默認值):左對齊。

  • flex_end :右對齊。

  • center : 居中。

  • space_between :兩端對齊,項目之間的間隔都相等。

  • space_around :每一個項目兩側的間隔相等。項目之間的間隔比項目與邊框的間隔大一倍。

下面咱們在xml中添加 justifyContent 屬性,設置右對齊:

app:justifyContent="flex_end"
複製代碼

運行後的效果以下圖:

若是須要在項目的排列方向上均分剩餘的空間怎麼辦呢?很簡單space_around屬性就是這樣的,效果以下圖

alignItems

alignItems 屬性定義項目在副軸軸上如何對齊,咱們經過一張圖來了解這個屬性比較直觀一點。

  • flex_start:交叉軸的起點對齊。

  • flex_end:交叉軸的終點對齊。

  • center:交叉軸的中點對齊。

  • baseline: 項目的第一行文字的基線對齊。

  • stretch(默認值):若是項目未設置高度或設爲auto,將佔滿整個容器的高度。

這也是爲何咱們的每個項目的高度都是不相同的,可是能夠看到前面每一個項目的高度都是同樣的,由於默認屬性 stretch 讓每一個項目的高度設置爲了填滿容器的高度(這裏的高度是指同一軸上的最高高度) 如今咱們設置對齊方式爲中心對齊,添加屬性:

app:alignItems="center"
複製代碼

運行後的效果以下圖:

能夠看到是根據每一個項目的中心對齊,這裏單獨說一下baseline屬性,熟悉ConstraintLayout的同窗應該比較好理解這個屬性,其實就是按照項目內的文本線來對齊項目。效果以下

能夠看到項目對齊是按照項目內的文本基線來對齊的。很好理解!須要注意的是項目中若是有的沒有文本基線,那麼默認他的基線就是左上角也就是起點左右位置。

alignContent

alignContent 屬性定義了多根軸線的對齊方式。若是項目只有一根軸線,該屬性不起做用。

  • flex_start:與交叉軸的起點對齊。

  • flex_end:與交叉軸的終點對齊。

  • center:與交叉軸的中點對齊。

  • space_between:與交叉軸兩端對齊,軸線之間的間隔平均分佈。

  • space_around:每根軸線兩側的間隔都相等。因此,軸線之間的間隔比軸線與邊框的間隔大一倍。

  • stretch(默認值):軸線佔滿整個交叉軸。

alignContentjustifyContent 其實裏面的屬性值都是同樣的 ,一個是設置主軸的對齊方式,一個是設置多個軸的對齊方式,通俗的講能夠理解爲好比是項目是水平換行,justifyContent就是設置垂直方向的對齊方式,若是項目是垂直方向對齊方式,那麼justifyContent就是設置水平方向的對齊方式。如今咱們想讓每一個項目距離上右下左的距離是同樣的,須要把alignContentjustifyContent都設置爲space_around就能夠了。

app:alignContent="space_around"
app:justifyContent="space_around"
複製代碼

運行後的效果以下圖:

showDividerHorizontal

showDividerHorizontal 控制顯示水平方向的分割線,值爲none | beginning | middle | end其中的一個或者多個。

dividerDrawableHorizontal

dividerDrawableHorizontal 設置Flex 軸線之間水平方向的分割線。

showDividerVertical

showDividerVertical 控制顯示垂直方向的分割線,值爲none | beginning | middle | end其中的一個或者多個。

dividerDrawableVertical

dividerDrawableVertical 設置子元素垂直方向的分割線。

showDivider

showDivider 控制顯示水平和垂直方向的分割線,值爲none | beginning | middle | end其中的一個或者多個。

dividerDrawable

dividerDrawable 設置水平和垂直方向的分割線,可是注意,若是同時和其餘屬性使用,好比爲 Flex 軸、子元素設置了justifyContent="space_around"alignContent="space_between" 等等。可能會看到意料不到的空間,所以應該避免和這些值同時使用。

子元素屬性

除以上以外,FlexboxLayout 不只有自身的屬性,還能夠設置子元素的屬性。這也是 FlexboxLayout 能完成聰明佈局的緣由之一。

layout_order

默認狀況下子元素的排列方式按照文檔流的順序依次排序,而 order 屬性能夠控制排列的順序,負值在前,正值在後,按照從小到大的順序依次排列。簡而言之就是你能夠定義子元素的排列順序。

咱們給子元素加上 order 屬性而且自定義他們的順序。

layout_flexGrow

layout_flexGrow 屬性定義項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大。其實就是 LinearLayout 中的weight屬性,若是全部項目的layout_flexGrow 屬性都爲1,則它們將等分剩餘空間。若是一個項目的layout_flexGrow 屬性爲2,其餘項目都爲1,則前者佔據的剩餘空間將比其餘項多一倍

layout_flexShrink

layout_flexShrink 屬性定義了項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小(設置了換行則無效)。若是全部項目的 layout_flexShrink 屬性都爲1,當空間不足時,都將等比例縮小。若是一個項目的 flex-shrink 屬性爲0,其餘項目都爲1,則空間不足時,前者不縮小。負值對該屬性無效。

layout_alignSelf

layout_alignSelf 屬性容許單個子元素有與其餘子元素不同的對齊方式,可覆蓋 alignItems 屬性。默認值爲auto,表示繼承父元素的 alignItems 屬性,若是沒有父元素,則等同於stretch

  • auto (default)

  • flex_start

  • flex_end

  • center

  • baseline

  • stretch

該屬性可能取6個值,除了auto,其餘都與align_items屬性徹底一致,咱們設置alignItemsflex_start屬性,其中一個子元素設置layout_alignSelf屬性爲baseline

baseline的基線是第一個元素的 baseline基線。

layout_flexBasisPercent

layout_flexBasisPercent 屬性定義了在分配多餘空間以前,子元素佔據的主軸空間的百分比。它的默認值爲auto,即子元素的原本大小。

咱們設置第一個和第三個都佔據的主軸空間的80%,給子元素添加屬性

app:layout_flexBasisPercent
複製代碼

FlexboxLayout 的屬性基本講解完了,若是一臉懵逼那麼請 看第二遍。FlexboxLayout 能幫你完成各類你須要的佈局,可謂 LinearLayout 的增強版。好比咱們須要作一個相似於Tag標籤的佈局,那麼 FlexboxLayout 能幫你輕輕鬆鬆實現。這裏須要用到 FlexboxLayoutManager,也就是 FlexboxLayoutRecycleView 提供的佈局管理器 佈局中添加RecycleView。

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
複製代碼

代碼中對RecycleView添加布局管理器,並設置 FlexboxLayout 的主屬性

RecyclerView recyclerView = findViewById(R.id.recyclerView);
    FlexboxLayoutManager flexboxLayoutManager = new FlexboxLayoutManager(this);
    flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP);
    flexboxLayoutManager.setFlexDirection(FlexDirection.ROW);
    flexboxLayoutManager.setAlignItems(AlignItems.STRETCH);
    flexboxLayoutManager.setJustifyContent(JustifyContent.FLEX_START);
    recyclerView.setLayoutManager(flexboxLayoutManager);
複製代碼

運行後的效果以下圖:

輕輕鬆鬆實現了Tag標籤的效果,是否是很簡單,一樣的方式咱們還能夠實現一個圖片流佈局。

FlexboxLayout的使用如今已經講解完了,相信各位對這個控件的強大已經有所瞭解了,不妨親自動手感覺下這個控件的強大。Google開放了愈來愈多的控件和開發輔助工具,對於開發者的咱們來講固然是好的。固然咱們本身也要保持一顆熱愛學習的心,不要抗拒新的東西,不斷學習 充實本身! 知行合一。



reference

相關文章
相關標籤/搜索