code小生,一个专注 Android 领域的技术分享平台

作者:埃赛尔
地址:https://www.jianshu.com/p/9cc89e033a9f
声明:本文来自 埃赛尔 投稿,转发等请联系原作者授权

1 . 前言

前几天看到Google官方的博客介绍了Google开源的一个强大的布局-FlexboxLayout,看见第一眼我心里的想法是,卧槽,Android 居然有这么一个强大的布局。作为一个有好奇心的工程狮,当然第一时间就去试了试手,效果非常赞,因此这篇文章就介绍一下它的用法和最新版添加的一些特性(支持集成RecyclerView),Github地址:https://github.com/google/flexbox-layout 。本文目录如下:

image

2 . 什么是FlexboxLayout

那么FlexboxLayout 它到底是个什么东西呢?看一下Github对这个库的介绍:FlexboxLayout is a library project which brings the similar capabilities of CSS Flexible Box Layout Module to Android. 意思是:FlexboxLayout是一个Android平台上与CSS的 Flexible box 布局模块 有相似功能的库。Flexbox 是CSS 的一种布局方案,可以简单、快捷的实现复杂布局。FlexboxLayout可以理解成一个高级版的LinearLayout,因为两个布局都把子view按顺序排列。两者之间最大的差别在于FlexboxLayout具有换行的特性。

3 .添加依赖:

    implementation 'com.google.android:flexbox:1.0.0'

4 . FlexboxLayout支持的属性介绍

上面说了FlexboxLayout真正强大的是它定义的属性,那么这一节我们看一下Flexbox支持哪些属性,分为2个方面,FlexboxLayout支持的属性和FlexboxLayout 子元素支持的属性:

FlexboxLayout 支持的属性:

flexDirection
flexDirection属性决定了主轴的方向,即FlexboxLayout里子Item的排列方向,有以下四种取值:

  • row (default): 默认值,主轴为水平方向,起点在左端,从左到右。

  • row_reverse:主轴为水平方向,起点在右端,从右到左。

  • column:主轴为竖直方向,起点在上端,从上到下。

  • column_reverse:主轴为竖直方向,起点在下端,从下往上。

文字有点苍白无力,看一下四种排列的对比,就明白了:

image

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:第一行内容的的基线对齐。
    文字显示有些苍白无力,用一张图来对比看一下,更好理解(图片来自Google 开源的 Android 排版库:FlexboxLayout):

image

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" 等等。可能会看到意料不到的空间,因此应该避免和这些值同时使用。

5 . FleboxLayout子元素支持的属性介绍

FlexboxLayout 子元素支持的属性:

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值。

6 . 与RecyclerView 的结合

在最新的alpha版本,Flexbox能够作为一个LayoutManager(FlexboxlayoutManager) 用在RecyclerView里面,这也就意味着你可以在一个有大量Item的可滚动容器里面使用Flexbox了。

来看一下继承RecyclerView 使用的示例:

  tab_layout.layoutManager = FlexboxLayoutManager(view.context, FlexDirection.ROW, FlexWrap.WRAP)

由于RecyclerView 的一些特性,Flexbox 的一些属性在FlexboxLayoutManager中没有实现,下面是FlexboxLayout和FlexboxLayoutManager支持的属性的对比:

支持属性的异同.png

注意红框中圈出来的属性,FlexboxlayoutManager是支持View回收的,而FlexboxLayout是不支持View回收的,FlexboxLayout只适用于少量Item的场景,这也是为什么会出现FlexboxLayoutManager的原因吧.

7 . 总结

FlexboxLayout 是 Google 去年开源的一个与 CSS Flexbox 有类似功能的强大布局,具有换行特性,使用起来特别方便,但是,FlexboxLayout 是没有考虑 View回收的,因此,它只使用于只有少量子 Item 的场景,如果向其中添加大量 Item 是灰导致内存溢出的。所幸,最新的版本添加了与 RecyclerView 的集成,这就可以在有大量子Item的场景下使用了,只是最新的版本还是 alpha 版,还没有出稳定的版本,相信不久后就能使用稳定的版本了。另外,FlexboxLayout 的这写属性的意义可能不好理解 ,建议大家去写个 demo 试一下每个属性的每个值看看是什么效果,这样就能很好的理解每个属性了。

技术推荐

善用 Android Studio 的异动管理功能

号外!号外!全网第一手Android P刘海屏适配大揭秘,唯一Kotlin算法


更多相关文章

  1. 浅谈Android布局样式
  2. Android样式:selector(选择器)
  3. Android的Intent Filter详解
  4. Android中自定义ListView无法响应OnItemClickListener中的onItem
  5. Android(安卓)ellipsize的几种属性值介绍
  6. 【笔记】【从Android(安卓)Guide温习Android(安卓)三】意图 (Int
  7. Android(安卓)uiautomator实例使用
  8. 给android系统添加自己想要的属性
  9. android settings--简述获取部分系统属性

随机推荐

  1. 深入理解 Android消息处理系统的原理
  2. [置顶] 【Android】 基于XMPP Smack框架
  3. Android Manifest标签之manifest,meta-da
  4. 【Unity3D】Unity3D与Android的交互通信(A
  5. Android(安卓)Studio 简单介绍和使用问题
  6. android开发资源合集
  7. Android: TextView常用属性的用法详解
  8. [置顶] 对Android(安卓)MVVM的理解
  9. Android中MPAndroidChart自定义绘制最高
  10. 【Android开发】基本组件-图像视图