来自CSS的Flexbox for Android

作者: 皮球二二 | 来源:发表于2016-06-24 21:46 被阅读248次

    今天给大家介绍一个新的控件,这个是谷歌在3个月之前的一天突然在GitHub上发布的。他的介绍言简意赅Flexbox for Android。Flexbox 的概念是从CSS Flexible Box Layout 模块中得到相应的灵感,然后把它的理念搬到Android上面来的。以我现在的水平来看,我觉得他就是为了方便我们实现FlowLayout的功能,以及在某种程度上替代GridView与GridLayout而生,至于我说的对不对,请大家多多给点意见

    基本概念

    axis

    将上图模型中包含的重要概念明确下
    main axis 主轴,子元素通过主轴来排列,如上图是从左往右。
    corss axis 侧轴就是与主轴垂直的轴
    这2个概念是后续官方描述中经常提到的概念

    加载

    加载过程没有什么不同,compile下就好了

    dependencies {
        compile 'com.google.android:flexbox:0.2.2'
    }
    

    加载完成了我们就可以使用了,如果你想看看动图特效,可以直接去Github上直接查看

    父元素属性

    先上布局文件,大致看看怎么写的

    <com.google.android.flexbox.FlexboxLayout xmlns:app="http://schemas.android.com/apk/res-auto"
        app:flexDirection="row"
        app:flexWrap="wrap"
        app:justifyContent="flex_start"
        app:alignItems="flex_start"
        app:alignContent="flex_start"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:text="Hello1Hello1Hello1Hello1Hello1Hello1"
            android:layout_width="100dip"
            android:layout_height="70dip"
            android:background="@android:color/holo_red_light"
            android:gravity="center"/>
        <TextView
            android:text="Hello2"
            android:layout_width="100dip"
            android:layout_height="70dip"
            android:background="@android:color/holo_blue_bright"
            android:gravity="center"/>
        <TextView
            android:text="Hello3Hello3Hello3Hello3Hello3"
            android:layout_width="100dip"
            android:layout_height="70dip"
            android:background="@android:color/holo_green_light"
            android:gravity="center"/>
        <TextView
            android:text="Hello4Hello4"
            android:layout_width="100dip"
            android:layout_height="70dip"
            android:background="@android:color/holo_purple"
            android:gravity="center"/>
        <TextView
            android:text="Hello5Hello5Hello5"
            android:layout_width="100dip"
            android:layout_height="70dip"
            android:background="@android:color/holo_orange_light"
            android:gravity="center"/>
    </com.google.android.flexbox.FlexboxLayout>
    

    主要的有这5个属性

    app:flexDirection
    app:flexWrap
    app:justifyContent
    app:alignItems
    app:alignContent
    
    • flexDirection: 决定了FlexBodyLayout中子View的方向
    <attr name="flexDirection">
        <enum name="row" value="0"/>
        <enum name="row_reverse" value="1"/>
        <enum name="column" value="2"/>
        <enum name="column_reverse" value="3"/>
    </attr>
    

    row: 水平方向由左往右排列
    row_reverse: 这是反向的,水平方向由右往左排列
    column: 垂直方向由上往下排列
    column_reverse: 这也是反向的,垂直方向由下往下上排列

    来看看效果是什么样的。注意每一个Item上面的文字,以备于同后续做对比

    row row_reverse column column_reverse
    • flexWrap: 这个属性用来控制排列到底是一行排完还是多行排完,还是正常方向排还是反方向排
    <attr name="flexWrap">
        <enum name="nowrap" value="0"/>
        <enum name="wrap" value="1"/>
        <enum name="wrap_reverse" value="2"/>
    </attr>
    

    nowrap: 不换行排
    wrap: 换行排
    wrap_reverse: 反方向换行排

    nowrap wrap wrap_reverse
    • justifyContent: 这个属性用来控制主轴上的对齐方式
    <attr name="justifyContent">
        <enum name="flex_start" value="0"/>
        <enum name="flex_end" value="1"/>
        <enum name="center" value="2"/>
        <enum name="space_between" value="3"/>
        <enum name="space_around" value="4"/>
    </attr>
    

    flex_start: 与起始位置对齐(比如你设置的flexDirection是row,那么起始位置就是左边,采用左对齐)
    flex_end: 与终止位置对齐(比如你设置的flexDirection是row,那么终止位置就是右边,采用右对齐)
    center: 居中对齐(这个不是在ViewGroup中间的意思,仅仅是在他位置的主轴方向居中)
    space_between: 两端对齐,Item之间的间隔都相等
    space_around: 这个不知道怎么翻译了,效果就是每个Item之间的间隔相等

    flex_start flex_end center space_between space_around
    • alignItems 刚设置了主轴的属性,现在到了侧轴了。当然,有个前提,如果你项目中轴线不止一根,那么久不起作用了。多根轴线需要align-content
    <attr name="alignItems">
        <enum name="flex_start" value="0"/>
        <enum name="flex_end" value="1"/>
        <enum name="center" value="2"/>
        <enum name="baseline" value="3"/>
        <enum name="stretch" value="4"/>
    </attr>
    

    flex_start: 与起始位置对齐(比如你设置的flexDirection是row,那么起始位置就是左边,采用上对齐)
    flex_end: 与终止位置对齐(比如你设置的flexDirection是row,那么终止位置就是右边,采用下对齐)
    center: 居中对齐(这个不是在ViewGroup中间的意思,仅仅是在他位置的侧轴方向居中)
    baseline: 与项目的第一行文字的基线对齐
    stretch: 如果项目未设置高度或设为auto,那么高度将占满整个容器

    flex_start flex_end center baseline stretch
    • alignContent: 此属性定义了多根轴线的对齐方式,如果只有一根轴线,将不起作用
    <attr name="alignContent">
        <enum name="flex_start" value="0"/>
        <enum name="flex_end" value="1"/>
        <enum name="center" value="2"/>
        <enum name="space_between" value="3"/>
        <enum name="space_around" value="4"/>
        <enum name="stretch" value="5"/>
    </attr>
    

    flex_start: 与起始位置对齐(比如你设置的flexDirection是row,那么起始位置就是左边,采用上对齐)
    flex_end: 与终止位置对齐(比如你设置的flexDirection是row,那么终止位置就是右边,采用下对齐)
    center: 居中对齐(这个不是在ViewGroup中间的意思,仅仅是在他位置的侧轴方向居中)
    space_between: 两端对齐,每一个轴之间的间隔都相等
    space_around: 这个不知道怎么翻译了,效果就是每个轴之间的间隔相等
    stretch: 如果项目未设置高度或设为auto,那么高度将占满整个容器

    flex_start flex_end center space_between space_around stretch

    子元素属性

    对父元素属性介绍完毕之后,我们再来说说子元素

    • layout_order: 这个可以更改视图的顺序,负值在前正值在后,默认为1。
      我现在将第二个item的layout_order值变成0,看看效果图
    layout_order

    到第一个来了,优先级最高

    • layout_flexGrow 这个属性的意思是,一旦有剩余空间可以放大,这个值决定了同一行中这个Item可以放大的比例。默认值是0,就是有空间也不放大。如果每个Item的layout_flexGrow值一样大,那么他们将均分这个剩余空间;如果某个值稍微大一些, 那么他分配的也稍微多一些。
      我现在将第二个item的layout_flexGrow值变成1,看看效果图
    layout_flexGrow

    占满了。

    然后我又给1、3均加上layout_flexGrow="1"

    layout_flexGrow

    均分剩余空间了

    • layout_flexShrink 有了放大也有缩小了,默认值为1,意思是如果需要你缩小你就缩小。如果大家值都是一样的,那么大家就等比缩小

    我加了一个黑色的,大家可以与上图对比下,确实是等比缩小

    flex_start flex_start

    我现在将红色的第一个设置为0,红色部分恢复到之前的大小了,而其他几个元素都被压缩了


    flex_start flex_start

    如果数字越大,那么压缩比例就会越大,这里就不重复贴图了

    • layout_flexBasisPercent: 这个属性很好理解,视图占据主轴的空间比例。我们这边是row,所以我们给第四个紫色的加layout_flexBasisPercent="50%"之后,看看效果
    layout_flexBasisPercent

    占据一半空间了

    • layout_alignSelf: 该属性允许单个子元素有与其他子元素不一样的对齐方式,可覆盖父视图的alignItems属性。默认值为auto,表示继承父元素的alignItems属性。他一共有6种属性
    <attr name="layout_alignSelf">
        <enum name="auto" value="-1"/>
        <enum name="flex_start" value="0"/>
        <enum name="flex_end" value="1"/>
        <enum name="center" value="2"/>
        <enum name="baseline" value="3"/>
        <enum name="stretch" value="4"/>
    </attr>
    

    除了这个auto属性值,其他都与alignItems一致

    来看看具体效果,我们把第二个textview的高度设置成wrap_content,然后添加app:layout_alignSelf="flex_start"

    layout_alignSelf

    再换成app:layout_alignSelf="flex_end"属性

    layout_alignSelf
    • **layout_minWidth / layout_minHeight (dimension) **
      layout_maxWidth / layout_maxHeight (dimension):
      最大最小高度、宽度没什么好说,其实跟layout_flexShrink、layout_flexGrow的概念差不多,不管你怎么压榨我这一行,我始终就是这么大

    • layout_wrapBefore (boolean): 叫你换行你就换行
      我们在第二个textView上面加了换行的要求

    layout_wrapBefore

    果断换行了

    OK,今天的介绍就结束了,希望大家能够自己积极思考这个控件的使用场景,相信谷歌推出它一定有它的意义

    主要参考文章

    前端基础(二)--快速布局神器Flexbox布局
    Android弹性布局(FlexboxLayout)

    相关文章

      网友评论

        本文标题:来自CSS的Flexbox for Android

        本文链接:https://www.haomeiwen.com/subject/ngmodttx.html