详解FlexboxLayout的使用

来源:互联网 发布:红尘网络旗舰店 编辑:程序博客网 时间:2024/06/05 06:15

概念

  google开源的一套解决复查布局的控件,可以替换Anddroid里的LinearLayout+RelativeLayout,

  最重要差异在于 FlexboxLayout 具有 “换行” 的特性,可便捷的写出流式布局。

场景


使用

  安装配置

  bulid.gradle文件(module)

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

 

实现

xml实现

<?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"    android:layout_width="match_parent"    android:layout_height="wrap_content"    app:flexDirection="row"    app:justifyContent="space_around"    app:flexWrap="wrap">    <TextView        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="吃货"        android:layout_marginBottom="10dp"/>    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="逗比" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="创业者" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="上班这点事" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="影视天堂" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="大学生活" />    <TextView        android:padding="6dp"        android:layout_marginBottom="10dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="单身狗" />    <TextView        android:padding="6dp"        android:layout_marginBottom="10dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="运动和健身" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="网购达人" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="旅游" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="程序员" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="追星族" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="短篇小说" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="美食" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="教育" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="教育" />    <TextView        android:layout_marginBottom="10dp"        android:padding="6dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/shape_text"        android:text="汪星人" /></com.google.android.flexbox.FlexboxLayout>



效果:

代码实现

效果

属性讲解

  直接在布局加入,如下:

<?xml version="1.0" encoding="utf-8"?><com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">    <TextView  android:text="textview1"  android:id="@+id/textview1"  android:layout_width="wrap_content"  android:layout_height="wrap_content"/>
   <TextView
  android:text="textview2"  android:id="@+id/textview2"  android:layout_width="wrap_content"  android:layout_height="wrap_content"/>    <TextView  android:text="textview3"   android:id="@+id/textview3"   android:layout_width="wrap_content"   android:layout_height="wrap_content"  /></com.google.android.flexbox.FlexboxLayout>

  咱们先看下没有添加额外属性(FlexboxLayout的属性)的效果

  

  跟LinearLayout一样,默认是水平方向的

  代码动态加入,如下:

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);

  支持的属性

属性值说明备注

flexDirection

 

row默认值,主轴为水平方向,起点在左端

决定主轴的方向,

类似 LinearLayout 的 vertical 和 horizontal


row-reverse主轴为水平方向,起点在右端column主轴为垂直方向,起点在上沿column-reverse主轴为垂直方向,起点在下沿

flexWrap



nowrap


不换行

默认情况下 Flex 跟 LinearLayout 一样,

都是不带换行排列的,但是flexWrap

属性可以支持换行排列

wrap按正常方向换行wrap-reverse按反方向换行

justifyContent


flex-start


默认值,左对齐

 属性定义了项目

在主轴上的对齐方式

这三个值类似于gravity

flex-end:右对齐center居中space-between两端对齐,项目之间的间隔都相等 属性定义了项目 

在主轴上的对齐方式

 这两个类似于LinearLayout里的weight属性

space-around

每个项目两侧的间隔相等。所以,

项目之间的间隔比项目与边框的间隔大一倍

alignContent



flex-start

交叉轴的起点对齐

定义了多根轴线的对齐方式。

如果项目只有一根轴线,该属性不起作用,

这个属性需要下面会着重讲下,因为网上很多论坛都

是千篇一律的一笔带过,压根看不懂。




flex-end交叉轴的终点对齐center交叉轴的中点对齐baseline项目的第一行文字的基线对齐stretch

默认值,如果项目未设置高度或设为auto,

将占满整个容器的高度

alignItems


flex-start交叉轴的起点对齐

定义项目在副轴轴上如何对齐,

 该属性与alignContent区别在于,alignContent只对多

行起作用,而alignitem对每一行都起作用,下面看效果

flex-end交叉轴的终点对齐center交叉轴的中点对齐baseline项目的第一行文字的基线对齐stretch

默认值,如果项目未设置高度或设为auto,

将占满整个容器的高度

layout_order-子控件

  这个属性主要用于子控件的,

可以控制排列的顺序,负值在前,

 正值灾后,按照从小到大的顺序依次排列

layout_flexGrow-子控件

 默认为0跟LinearLayout的weight类似 定义项目的放大比例layout_flexShrink-子控件默认为1 定义了项目的缩小比例layout_alignSelf-子控件  与align-item相同layout_flexBasisPercent-子控件百分数

只有在父布局为

MeasureSpec的值

 MeasureSpec.EXACTLY

属性定义了在分配多余空间之前,子元素

占据的main size主轴空间,浏览器根据

这个属性,计算主轴是否有多余空间。

它的默认值为auto,即子元素的本来大小(不知讲的啥。。。还是看效果吧)

layout_minWidth / layout_minHeight  item 的最小宽度/高度layout_maxWidth / layout_maxHeight  item 的最大宽度/高度layout_wrapBefore  

item 是否在 flex line 的第一个,默认为 false,

在父布局app:flexWrap="nowrap"时不起作用

 

  • flexDirection

    • row-reverse:主轴为水平方向,起点在右端。

    • column-reverse:主轴为垂直方向,起点在下沿

      水平反向与垂直反向

         

         

  • flexWrap

          换行属性。我们把上面的demo加上该属性试试,首先我们先把水平方向填满

          

        然后分别加上flexWrap属性,值为wrap,wrap-reverse

        

      发现两个都换行了,而且reverse的时候,是最后添加的text3在最上面

  • justifyContent

        
        

       
       可以看到前三个属性类似gravity,而后两个类似于LinearLayout里的weight属性

  • alignContent  

         属性定义项目在副轴轴上如何对齐

         这里解释下什么是主/副轴,看图:

         
         这个属性什么情况下起作用呢?
         当主轴是水平方向时,只有存在多行的情况下,这个属性才起左右,如图:
          
         添加了没有任何效果,咱们现在换成多行试试:
         

alignItem

单行的情况下也生效

子控件属性

  • layout_order

        看下添加该属性前后的效果对比图
       
  • layout_flexBasisPercent

    只有在父布局为MeasureSpec.EXACTLY(
    wrap_parent -> MeasureSpec.AT_MOST
    match_parent -> MeasureSpec.EXACTLY
    具体值 -> MeasureSpec.EXACTLY)
    时生效,设置三个模式看下效果
    wrap_parent(没有效果)                                                                     match_parent(有效果)                                                     指定值(有效果)
  • layout_wrapBefore

    对比下设置的效果
     

          

项目应用

  看下是否能替换咱们APP里的布局,找了好几个页面,发现只有个人中心→设置→

  更多→关于 这个页面稍微简单点,而且里面是LinearLayout+RelativeLayout的组合

  效果图及布局文件结构如下:

  

  尝试着用FlexboxLayout替换这个布局,目的:去掉所有的RelativeLayout与LinearLayout,

  而且只有一个FlexboxLayout与所有的子控件。但是经过分析发现,没法到这个目标,因为

  这个页面里既有水平方向又有垂直方向的,而且底部还有一个利用RelativeLayout的

  layout_alignParentBottom="true"属性设置的,而FlexboxLayout也没有这个属性,虽然可以

  用FlexboxLayout的alignContent="flex_end"有这效果,但必须是水平的父布局,所以不能完全

  利用FlexboxLayout来替换该布局。突然想起里前面介绍里说过的一句话:

  “最重要差异在于 FlexboxLayout 具有 “换行” 的特性,可便捷的写出流式布局”。

结论

  适用场景

  • 自动换行
  • 流式布局

问题

  问题:

    Failed to resolve: com.google.android:flexbox:0.2.6

  解决:

  把最外层的build.gradle里配置的两个jcenter由默认的

 jcenter()改为
 jcenter{    url 'http://jcenter.bintray.com/' }

Demo链接

参考

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

0 0
原创粉丝点击