Android弹性布局-FlexboxLayout

Flexbox简介

简单来说 Flexbox 是属于web前端领域CSS的一种布局方案,是2009年W3C提出了一种新的布局方案,可以简便、完整、响应式地实现各种页面布局,并且 React Native 也是使用的 Flex 布局。谷歌将其引入以提高复杂布局的能
力。

Github 源码传送门

Flexbox的布局和相关名称

上图模型中包含以下概念

  1. flex container 父容器,用来包含子元素,对应于FlexboxLayout类。
  2. flex item 子元素,父容器直接包裹的元素。
  3. main axis 主轴,子元素通过主轴来排列,如上图是从左往右。
  4. corss axis 副轴,垂直于主轴的第二个轴
  5. main start,main end 父容器中主轴开始和结束的边界,子元素从main start往main end的方向排列(如果主轴是水平,起点在左端,main start,main end 用来控制子元素从左向右排列)
  6. cross start,corss end 父容器中副轴开始和结束的边界。子元素从cross start往cross end方向排列(如果主轴是水平的,那么副轴就是垂直的,假设如上图,cross start 在上,cross end 在下,那么子元素就是从上往下排列)

使用方式

使用方式很简单,只需要添加以下依赖:

compile ‘com.google.android:flexbox:0.1.2’

Flexbox 布局示例

<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(FlexboxLayout.FLEX_DIRECTION_COLUMN);

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

属性介绍

Contatiner的属性

flexDirection

flexDirection 属性决定主轴的方向(即子元素的排列方向)。类似 LinearLayout 的 vertical 和 horizontal。决定主轴和副轴的方向,有以下四个值:

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。

而副轴是和主轴垂直的方向,起点相同。

flexWrap

控制单行和多行,以及副轴的方向。默认情况下 Flex 跟 LinearLayout 一样,都是不带换行排列的,但是flexWrap属性可以支持换行排列。这个也比 LinearLayout 吊啊有三个值:

  • nowrap (default) 不换行
  • wrap 换行
  • wrap_reverse 副轴方向置反

justifyContent

justifyContent属性定义了项目在主轴上的对齐方式。

  • flex-start(default):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

alignItems

控制沿副轴对齐(单行起作用)

  • stretch(default):如果项目未设置高度或设为auto,将占满整个容器的高度。
  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。

alignContent

alignContent属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

  • stretch(default):轴线占满整个交叉轴。
  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

子元素的属性

layout_order

控制子元素布局的顺序,默认值为1,顺序为XML中元素的顺序.默认情况下子元素的排列方式按照文档流的顺序依次排序,而order属性可以控制排列的顺序,负值在前,正值灾后,按照从小到大的顺序依次排列。

layout_flexGrow

layout_flexGrow 属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。一张图看懂。跟 LinearLayout 中的weight属性一样。


如果所有项目的 layout_flexGrow 属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的 layout_flexGrow 属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

layout_flexShrink

layout_flexShrink 属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

layout_alignSelf

允许单个元素有不一样的对齐方式,会覆盖align-item,除auto外,其他取值都和align-item的含义一致。
默认值为auto,表示继承父元素的 alignItems 属性,如果没有父元素,则等同于stretch。

  • flex_start
  • flex_end
  • center
  • baseline
  • stretch

layout_flexBasisPercent

只能为百分比的值,只有父元素是MeasureSpec.EXACTLY的模式时才有效。
layout_flexBasisPercent 属性定义了在分配多余空间之前,子元素占据的main size主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即子元素的本来大小。

与传统CSS弹性布局不同之处

  1. 没有flex-flow属性 :因为没必要
  2. 没有flex属性:同样没必要
  3. layout_flexBasisPercent 替代了flexBasis。如果子元素宽高确定了,可以指定具体值或百分比,如果是包裹内容,那只能是百分比
  4. 不支持min-width和min-height:因为谷歌还没实现

相关链接:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://github.com/google/flexbox-layout/wiki
https://blog.stylingandroid.com/flexboxlayout-part-1/

文章来源:
简书
AndroidDeveloper微信公众号-stormzhang

-------------本文结束 感谢阅读-------------
坚持好文章的分享,您的支持将是对我最大的鼓励!