android開發筆記之可伸縮佈局FlexboxLayout

可伸縮佈局FlexboxLayout

gitbug flexbox-layout
https://github.com/google/flexbox-layout

FlexboxLayout官方定義:
FlexboxLayout is a library project which brings the similar capabilities of CSS Flexible Box Layout Module to Android.

佈局文件的一個官方樣例:

<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"
    app:flexWrap="wrap"
    app:alignItems="stretch"
    app:alignContent="stretch" >

    <TextView
        android:id="@+id/textview1"
        android:layout_width="120dp"
        android:layout_height="80dp"
        app:layout_flexBasisPercent="50%"
        />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="80dp"
        android:layout_height="80dp"
        app:layout_alignSelf="center"
        />

    <TextView
        android:id="@+id/textview3"
        android:layout_width="160dp"
        android:layout_height="80dp"
        app:layout_alignSelf="flex_end"
        />
</com.google.android.flexbox.FlexboxLayout>

實踐代碼:

FlexboxLayout flexboxLayout = (FlexboxLayout) findViewById(R.id.flexbox_layout);
flexboxLayout.setFlexDirection(FlexDirection.ROW);

View view = flexboxLayout.getChildAt(0);
FlexboxLayout.LayoutParams lp = (FlexboxLayout.LayoutParams) view.getLayoutParams();
lp.order = -1;
lp.flexGrow = 2;
view.setLayoutParams(lp);

FlexboxLayoutManager (within RecyclerView):

RecyclerView recyclerView = (RecyclerView) context.findViewById(R.id.recyclerview);
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
layoutManager.setFlexDirection(FlexDirection.COLUMN);
layoutManager.setJustifyContent(JustifyContent.FLEX_END);
recyclerView.setLayoutManager(layoutManager);
mImageView.setImageDrawable(drawable);
ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
    FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
    flexboxLp.setFlexGrow(1.0f);
    flexboxLp.setAlignSelf(AlignSelf.FLEX_END);
}

在build.gradle添加依賴:

dependencies {
    implementation 'com.google.android:flexbox:1.0.0'
}

官網是要1.1.0,但是需要內置到AndroidX,我測試是android 8.1,所以我使用的是1.0.0版本。

Android Demo

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:flexWrap="wrap"
    app:alignItems="center"
    app:alignContent="flex_start"
    app:flexDirection="row"
    app:justifyContent="flex_start"
    app:showDivider="beginning|middle"
    tools:context=".FlexBoxLayoutMainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="01"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="02"
            app:layout_flexGrow="1"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_flexGrow="1"
            app:layout_alignSelf="flex_start"
            android:text="03"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_flexGrow="1"
            app:layout_alignSelf="flex_start"
            android:text="04"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="05"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="06"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="07"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="08"
            android:gravity="center" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            app:layout_alignSelf="flex_start"
            android:text="09"
            android:gravity="center" />

</com.google.android.flexbox.FlexboxLayout>

效果圖:
在這裏插入圖片描述

具體樣例

FlexboxLayout 支持的屬性:

flexDirection

flexDirection屬性決定了主軸的方向,即FlexboxLayout裏子Item的排列方向,有以下四種取值:
row (default): 默認值,主軸爲水平方向,起點在左端,從左到右。
row_reverse:主軸爲水平方向,起點在右端,從右到左。
column:主軸爲豎直方向,起點在上端,從上到下。
column_reverse:主軸爲豎直方向,起點在下端,從下往上。
如圖:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

flexWrap

flexWrap 這個屬性決定Flex 容器是單行還是多行,並且決定副軸(與主軸垂直的軸)的方向。可能有以下3個值:
noWrap: 不換行,一行顯示完子元素。
wrap: 按正常方向換行。
wrap_reverse: 按反方向換行。

justifyContent

justifyContent 屬性控制元素主軸方向上的對齊方式,有以下5種取值:
flex_start (default): 默認值,左對齊
flex_end: 右對齊
center: 居中對齊
space_between: 兩端對齊,中間間隔相同
space_around: 每個元素到兩側的距離相等。

alignItems

alignItems 屬性控制元素在副軸方向的對齊方式,有以下5種取值:
stretch (default) :默認值,如果item沒有設置高度,則充滿容器高度。
flex_start:頂端對齊
flex_end:底部對齊
center:居中對齊
baseline:第一行內容的的基線對齊。

alignContent

alignContent 屬性控制多根軸線的對齊方式(也就是控制多行,如果子元素只有一行,則不起作用),可能有一下6種取值:
stretch (default): 默認值,充滿交叉軸的高度(測試發現,需要alignItems 的值也爲stretch 纔有效)。
flex_start: 與交叉軸起點對齊。
flex_end: 與交叉軸終點對齊。
center: 與交叉軸居中對齊。
space_between: 交叉軸兩端對齊,中間間隔相等。
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” 等等。可能會看到意料不到的空間,因此應該避免和這些值同時使用。

FleboxLayout子元素支持的屬性介紹

layout_order

layout_order 屬性可以改變子元素的排列順序,默認情況下,FlexboxLayout子元素的排列是按照xml文件中出現的順序。默認值爲1,值越小排在越靠前。

layout_flexGrow(float)

layout_flexGrow 子元素的放大比例, 決定如何分配剩餘空間(如果存在剩餘空間的話),默認值爲0,不會分配剩餘空間,如果有一個item的 layout_flexGrow 是一個正值,那麼會將全部剩餘空間分配給這個Item,如果有多個Item這個屬性都爲正值,那麼剩餘空間的分配按照layout_flexGrow定義的比例(有點像LinearLayout的layout_weight屬性)。

layout_flexShrink(float)

layout_flexShrink:子元素縮小比例,當空間不足時,子元素需要縮小(設置了換行則無效),默認值爲1,如果所有子元素的layout_flexShrink 值爲1,空間不足時,都等比縮小,如果有一個爲0,其他爲1,空間不足時,爲0的不縮小,負值無效。

layout_alignSelf

layout_alignSelf 屬性可以給子元素設置對齊方式,上面講的alignItems屬性可以設置對齊,這個屬性的功能和alignItems一樣,只不過alignItems作用於所有子元素,而layout_alignSelf 作用於單個子元素。默認值爲auto, 表示繼承alignItems屬性,如果爲auto以外的值,則會覆蓋alignItems屬性。有以下6種取值:
auto (default)
flex_start
flex_end
center
baseline
stretch
除了auto以外,其他和alignItems屬性一樣。

layout_flexBasisPercent (fraction)

layout_flexBasisPercent的值爲一個百分比,表示設置子元素的長度爲它父容器長度的百分比,如果設置了這個值,那麼通過這個屬性計算的值將會覆蓋layout_width或者layout_height的值。但是需要注意,這個值只有設置了父容器的長度時纔有效(也就是MeasureSpec mode 是 MeasureSpec.EXACTLY)。默認值時-1。

layout_minWidth / layout_minHeight (dimension)

強制限制 FlexboxLayout的子元素(寬或高)不會小於最小值,不管layout_flexShrink這個屬性的值爲多少,子元素不會被縮小到小於設置的這個最小值。

layout_maxWidth / layout_maxHeight (dimension)

這個和上面的剛好相反,強制限制FlexboxLayout子元素不會大於這個最大值, 不管layout_flexGrow的值爲多少,子元素不會被放大到超過這個最大值。

layout_wrapBefore

layout_wrapBefore 屬性控制強制換行,默認值爲false,如果將一個子元素的這個屬性設置爲true,那麼這個子元素將會成爲一行的第一個元素。這個屬性將忽略flex_wrap 設置的 noWrap值。

參考資料

1.Android可伸縮佈局-FlexboxLayout(支持RecyclerView集成)
http://www.cnblogs.com/huolongluo/p/6607877.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章