RelativeLayout
、LinearLayout
等常用布局相信大家早已耳熟能詳,今天給大家介紹一款新的布局方式「彈性布局」--FlexboxLayout。
Flex
是Flexible Box的縮寫,意為「彈性布局」,在前端css樣式中應用甚為廣泛,之前做過React-Native
和微信小程序,頁面布局大多使用flex彈性布局,可以在不同屏幕尺寸上提供一致的布局結構,可以簡便、完整、響應式地實現各種頁面布局,今天為大家打開Android
移動端的flex布局大門--FlexboxLayout
,在android中我們經常所見的標簽、流式布局等都可以用FlexboxLayout
來實現。
安裝
build 依賴
dependencies {
implementation 'com.google.android:flexbox:1.0.0'
}
FlexboxLayout 屬性介紹
flexDirection
flex-direction
屬性決定主軸的方向(即內部子元素的排列方向)。
row
(默認值):水平顯示,起點在左端row_reverse
:水平顯示,起點在右端,與row
相反的順序column
:垂直顯示,起點在頂部column_reverse
:垂直顯示,起點在底部,與column
相反的順序
xml中使用app:flexDirection="row"
,代碼中使用flexboxLayout.setFlexDirection(FlexDirection.ROW)
這里為了演示布局緊湊,不讓元素撐滿整個布局,xml里設置了
app:alignItems="flex_start"
,app:alignContent="flex_start"
,后續有對alignItems
和alignContent
的屬性介紹,讀者可以去除這兩個屬性看看演示效果。
flexWrap
flexWrap
決定是否換行
nowrap
(默認值):不換行wrap
:按正常方向換行,第一行在上方wrap_reverse
:按反方向換行,第一行在下方
xml中使用app:flexWrap="nowrap"
,代碼中使用flexboxLayout.setFlexWrap(FlexWrap.NOWRAP)
justifyContent
justifyContent
決定元素在主軸上的對齊方式
flex_start
(默認值):主軸方向起點對齊flex_end
:主軸方向終點對齊center
: 主軸方向居中對齊space_between
:主軸方向兩端對齊,元素之間的間隔都相等。space-around
:每個元素兩側的間隔相等。所以,元素之間的間隔比元素與布局邊框的間隔大一倍。
xml中使用app:justifyContent="flex_start"
,代碼中使用flexboxLayout.setJustifyContent(JustifyContent.FLEX_START)
注意這里是 主軸方向 上的對齊方式即flexDirection
屬性,例如主軸如果是row
水平方向的,那么center
屬性就是水平居中,如果是column
,那么就是垂直方向居中。
alignItems
alignItems
決定元素在交叉軸方向上的對齊方式,「交叉軸」 我理解的就是 與主軸交叉垂直的方向,比如主軸是水平的,那么交叉軸就是垂直方向的
stretch
(默認值):交叉軸方向占滿整個父布局。flex_start
交叉軸的起點對齊flex_end
交叉軸的終點對齊。center
交叉軸的居中對齊baseline
元素第一行文字的基線對齊
默認值是stretch
,不管元素布局設置的寬高多少,都會在交叉軸方向占滿父布局,例如flexDirection
是默認row
水平方向,那么元素就會在垂直方向撐滿父布局。
一般會選擇使用flex_start
屬性,可以自由控制元素的大小。
alignContent
alignContent
決定了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
stretch
(默認值):軸線占滿整個交叉軸。flex_start
交叉軸方向起點對齊flex_end
交叉軸方向終點對齊center
交叉軸方向居中對齊space_between
交叉軸方向兩端對齊,元素之間的間隔都相等space_around
每個元素兩側的間隔相等。所以,元素之間的間隔比元素與布局邊框的間隔大一倍
alignContent
是在多行的情況下起作用。
justifyContent
設置主軸方向的對齊方式,alignContent
是設置交叉軸方向的對齊方式。例如元素是水平方向換行,justifyContent
設置center
屬性就是水平居中,alignContent
設置center
屬性就是垂直居中。
divider屬性
描述了元素間的分割線
showDividerHorizontal
四個屬性none | beginning | middle | end
,beginning顯示線條在布局的上面,end顯示線條在布局的下面dividerDrawableHorizontal
水平分隔線放在伸縮線之間showDividerVertical
beginning顯示線條在布局的左邊,end顯示線條在布局的右邊dividerDrawableVertical
垂直分隔線放在伸縮線之間showDivider
配合dividerDrawableHorizontal就是showDividerHorizontal的效果,配合dividerDrawableVertical就是showDividerVertical的效果,配合dividerDrawable就是顯示水平和垂直方向的線條dividerDrawable
drawable屬性,配合showDivider可以顯示水平和垂直方向的線條
app:alignContent="flex_start"
app:alignItems="flex_start"
app:flexWrap="wrap"
app:dividerDrawable="@drawable/divider"
app:showDivider="beginning|end|middle"
子元素屬性
除了給FlexboxLayout
自身設置屬性,還可以給到子元素設置屬性
layout_order
layout_order
可以改變元素排列順序,默認值是1,按順序排列的,值越大,排列越靠后
文字1的textView
的屬性app:layout_order="2"
,其余為默認1
layout_flexGrow
layout_flexGrow
決定元素的放大比例,默認不放大,值為0。如果一個元素的layout_flexGrow
屬性為2,其他元素為1,則前者占據的剩余空間將比其他的多一倍。屬性類似於LinearLayout
的weight
屬性。
三個view的app:layout_flexGrow
值分別為1、1、2
layout_flexShrink
layout_flexShrink
決定元素的縮小比例,默認為1,即當空間不足是,該元素被縮小。值越大,縮小比例越大,0的話則不縮小。空間足夠的情況,屬性無效。
三個view的app:layout_flexShrink
值分別為2、1、1
layout_alignSelf
layout_alignSelf
允許單個子元素有與其他子元素不一樣的對齊方式,默認值為auto
,繼承父元素的alignItems
屬性,其余屬性值同alignItems
屬性
第一個viewapp:layout_alignSelf="center"
垂直居中
layout_flexBasisPercent
layout_flexBasisPercent
決定了在分配多余空間之前,子元素占據的主軸空間的百分比。默認為自身大小
第一個viewapp:layout_flexBasisPercent="50%"
水平占比50%
與recyclerView搭配
FlexboxLayout的應用可謂廣泛,主流的tag標簽 流式布局就可以使用FlexboxLayout
動態添加view去實現,例外還可以使用RecyclerView
的布局管理器FlexboxLayoutManager
來完成流式布局。
FlexboxLayoutManager manager = new FlexboxLayoutManager(this);
manager.setFlexDirection(FlexDirection.ROW);
manager.setFlexWrap(FlexWrap.WRAP);
recyclerView.setLayoutManager(manager);
同樣圖片的流式布局原理相通,這里就不一一列舉。
最后附上github地址:https://github.com/taixiang/flexboxLayout
歡迎關注我的博客:https://blog.manjiexiang.cn/
歡迎關注微信號:春風十里不如認識你