Android上的Flexbox布局

splash 7年前發布 | 12K 次閱讀 Android開發 移動開發 flexbox

簡介

最近Google開源了一個叫 flex-box 的庫,它的思路是參照的 CSS的Flex布局 設計的,所以屬性基本都是和CSS上的Flex布局保持一致,但因為是兩個不同的平臺,所以減少了幾個不適用于Android的屬性,新增了幾個屬性,具體我們下面會說到。

關于CSS的Flex布局

在了解Google開源的 flex-box ,我覺得有必要先了解下 CSS的Flex布局 ,這有助于我們理解那些屬性定義。關于這方面的知識,可以閱讀這篇博客。下面我們只是簡要的了解下,具體屬性我們放到講解Google的 flex-box 中去說明。

//這段文字說明,來源于上面說到的博客
采用Flex布局的元素,稱為Flex容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為Flex項目(flex item),簡稱"項目"。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。
項目默認沿主軸排列。單個項目占據的主軸空間叫做main size,占據的交叉軸空間叫做cross size。

img

關于Google的flexbox-layout

注意:以下文中用到的flexbox-layout指的是Google開源的庫,Flex指的是CSS中的Flex布局。

首先我們需要知道的是,flexbox-layout的基本概念和Flex是一樣的,最外面的這層布局稱為 容器 ,在flexbox-layout指的是 com.google.android.flexbox.FlexboxLayout ,里面的子元素稱為 項目 。容器默認存在兩條軸,其中水平(這里是就上面的概念圖而言,因為主軸的方向是可以指定的)的這條軸稱為 主軸 (個人理解,可以存在多條,具體原因后面講),垂直的這條稱為 交叉軸 。其他屬性比如 start , end 等等也是一樣的,具體可以看上面的基本概念圖。

下面我們著重講下flexbox-layout支持的屬性,因為它既支持容器屬性,也支持項目屬性,所以我們分成兩個篇幅來說明。

注意:以下屬性設置的具體效果請參照說明文檔和Demo, github地址

容器屬性

  • flexDirection

    這個屬性用于確定 主軸方向 ,可選的值有:

    1. row 水平方向,起點在左邊。默認值
    2. row_revers 水平方向,起點在右邊。
    3. column 垂直方向,起點在上邊。
    4. column_reverse 垂直方向,起點在下邊。

 

 

  • flexWrap

這個屬性控制容器是單行還是自動換行,以及主軸的方向,可選的值有:

關于 wrap 和 wrap-reverse 的區別:

 

  1. nowrap 單行。默認值
  2. wrap 自動換行,第一行在上方
  3. wrap-reverse 自動換行,第一行在下方

justifyContent

這個屬性控制項目在主軸上的對齊方式,可選的值有:

注意:具體的對齊方式與主軸的方向有關,下面的說明是基于默認值

關于 space_between 和 space_around 的樣式如下:

 

  1. flex_start 左對齊,默認值
  2. flex_end 右對齊
  3. center 居中對齊
  4. space_between 兩端對齊,項目之間的間隔相等
  5. space_around 每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍
  • alignItems

這個屬性定義項目在交叉軸上的對齊方式,可選的值有:

注意:具體的對齊方式與主軸的方向有關

關于 stretch 和 baseline 的樣式如下:

Android上的Flexbox布局

  1. stretch 占滿整個容器高度,默認值
  2. flex_start 交叉軸的起點對齊
  3. flex_end 交叉軸的終點對齊
  4. center 居中對齊
  5. baseline 項目的第一行文字的基線對齊
  • alignContent

    這個屬性控制容器的多條主軸的對齊方式,這也是我們前面提到的 主軸可以有多條,當 flexWrap:wrap|wrapreverse 。可選的值有:

    注意:只有一條主軸,該屬性不起作用

    這里需要注意區別下和 alignItems 的區別, alignContent 是多條主軸基于交叉軸的對齊方式,而后者是項目基于交叉軸的對齊方式,一個是軸,一個是項目。

    1. stretch 占滿整個交叉軸,默認值
    2. flex_start 與交叉軸的起點對齊
    3. flex_end 與交叉軸的終點對齊
    4. center 與交叉軸的中心對齊
    5. space_between 與交叉軸兩端對齊,軸線之間的間隔平均分布
    6. space_around 每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍
  • showDividerHorizontal

  • dividerDrawableHorizontal

  • showDividerVertical

  • dividerDrawableVertical

  • showDivider

  • dividerDrawable

    這幾個屬性都是跟分隔符有關,具體用法可以看文檔。

項目屬性

  • layout_order(integer)

    這個屬性可以改變項目的排列順序,默認值為 1 。

  • layout_flexGrow(float)

    這個屬性定義項目基于當前行的放大比例,默認值為 0 。這個屬性類似 LinearLayout 中的 layout_weight 屬性,如果當前行只有一個項目的 layout_flexGrow 為正值,則該項目將占滿當前行剩余的空間,下面的效果是三個相同大小的項目,其中一個 layout_flexGrow 為正值的效果:

 

如果存在多個 layout_flexGrow 為正值的情況,則這幾個項目則會按設置的值為比例占用當前行剩余的空間,下面的效果是三個相同大小的項目,其中兩個項目設置 layout_flexGrow:1 的效果:

  • layout_flexShrink(float)

    這個屬性定義了項目的縮小比例,默認為 1 ,即如果當前行空間不足,該項目縮小的方式。

    如果所有項目的 layout_flexShrink 屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的 layout_flexShrink 屬性為0,其他項目都為1,則空間不足時,前者不縮小。

    個人理解,注意:要設置 flexWrap:nowrap 為單行

  • layout_alignSelf

    該屬性允許單個項目與其他項目不一樣的基于交叉軸的對齊方式。默認值為 auto ,即按照容器的 alignItems 屬性,設置其他值,則會覆蓋容器的值,可選的值:

    1. auto 默認值
    2. flex_start
    3. flex_end
    4. center
    5. baseline
    6. stretch
  • layout_flexBasisPercent(fraction)

    這個屬性設置項目長度相對于容器的百分比,如果設置了這個值,則從 layout_width 或 layout_height 指定的長度會被覆蓋,需要注意的是,這個屬性只在容器長度確定的情況下有效,即 MeasureSpec.EXACTLY 。默認值為 -1 ,表示不設置。

  • layout_minWidth/ layout_minHeight (dimension)

  • layout_maxWidth/ layout_maxHeight (dimension)

    這些屬性設置對項目的最大最小限制

  • layout_wrapBefore(boolean)

    這個屬性默認值為 false ,如果設置為 true ,則該項目將強制成為當前行的第一個項目,會忽略 flex_wrap:nowrap 設置。

應用實例

  1. 底部按鈕

 

2.流式布局

 

 

來自:https://juejin.im/post/58dde21461ff4b006b0b0cc4

 

 本文由用戶 splash 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!