FlexboxLayout的使用

匿名 (未验证) 提交于 2019-12-03 00:19:01

FlexboxLayout

本文是官方文档的翻译

FlexboxLayout 是一个库项目,能在Android上实现类似CSS Flexible Box Layout Module 的能力。

添加以下依赖到你的build.gradle 文件中:

dependencies {     implementation 'com.google.android:flexbox:1.0.0' }

在布局中有两种方式使用FlexBox

FlexboxLayout

第一种是像LinearLayoutRelativeLayout那样,FlexboxLayout 都是继承了 ViewGroup
你可以指定属性在一个布局XML,如:

<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(FlexDirection.ROW);  View view = flexboxLayout.getChildAt(0); FlexboxLayout.LayoutParams lp = (FlexboxLayout.LayoutParams) view.getLayoutParams(); lp.order = -1; lp.flexGrow = 2; view.setLayoutParams(lp);

FlexboxLayoutManager (within RecyclerView)

第二种方式是 FlexboxLayoutManager 可以使用在 RecyclerView的内部.

RecyclerView recyclerView = (RecyclerView) context.findViewById(R.id.recyclerview); FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context); layoutManager.setFlexDirection(FlexDirection.COLUMN); layoutManager.setJustifyContent(JustifyContent.FLEX_END); recyclerView.setLayoutManager(layoutManager);

或者通过孩子的属性的 FlexboxLayoutManager 你可以这样做:

mImageView.setImageDrawable(drawable); ViewGroup.LayoutParams lp = mImageView.getLayoutParams(); if (lp instanceof FlexboxLayoutManager.LayoutParams) {     FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;     flexboxLp.setFlexGrow(1.0f);     flexboxLp.setAlignSelf(AlignSelf.FLEX_END); }

使用FlexboxLayoutManager的优点是它可以回收从屏幕上消失的views,为了重用那些出现在用户滚动条上的视图而不是每次都inflate每个单独的view,
这样做可以消耗小得多的内存特别是当Flexbox容器包含了item的总数是很大的时候。

由于RecyclerView的一些特征,有些FlexBox的属性不可用或者没有实现在FlexboxLayoutManager
下面是两个实现之间的属性/特性比较的快速概述

Attribute / Feature FlexboxLayout FlexboxLayoutManager (RecyclerView)
flexDirection

flexWrap

(except wrap_reverse)
justifyContent

alignItems

alignContent

-
layout_order

-
layout_flexGrow

layout_flexShrink

layout_alignSelf

layout_flexBasisPercent

layout_(min/max)Width

layout_(min/max)Height

layout_wrapBefore

Divider

View recycling -

Scrolling *1

*1 部分可能用ScrollView来包装,但是它不太可能用作与一个大集合布局内部的视图,因为它不考虑到视图的回收

Attributes for the FlexboxLayout:

  • flexDirection

    • 这个属性决定了主轴的方向(交叉轴,垂直于主轴。子items根据方向放置到Flexbox布局中
      可能的值有:
    • row (default)
    • row_reverse
    • column
    • column_reverse

  • flexWrap

    • 这个属性控制flex container 是单行或者多行,和交叉轴的方向,可能的值有:
    • nowrap (default)
    • wrap
    • wrap_reverse

  • justifyContent

    • 这个属性控制主轴的对齐方式,可能的值有:
    • flex_start (default)
    • flex_end
    • center
    • space_between
    • space_around

  • alignItems

    • 这个属性控制交叉轴的对齐方式,可能的值:
    • stretch (default)
    • flex_start
    • flex_end
    • center
    • baseline

  • alignContent

    • 这个值控制flex的lines对齐方式在fiex容器中(只有多行的时候有效),可能的值:
    • stretch (default)
    • flex_start
    • flex_end
    • center
    • space_between
    • space_around

  • showDividerHorizontal (one or more of none | beginning | middle | end)

  • dividerDrawableHorizontal (reference to a drawable)
    *在flex线之间放置水平分隔物 (or flex items when flexDirection
    is set to column or column_rebase).

  • showDividerVertical (one or more of none | beginning | middle | end)

  • dividerDrawableVertical (reference to a drawable)

    • 在flex项目之间放置垂直分隔物 (or flex lines when flexDirection
      is set to column or column_rebase).
  • showDivider (one or more of none | beginning | middle | end)

  • dividerDrawable (reference to a drawable)

    • 同时设置水平和垂直的分割线。注意,如果与其他属性一起使用
      (such as justifyContent="space_around" or alignContent="space_between" … etc) 将
      在flex线或flex项目之间的空间,您可能会看到意想不到的空间。请避免使用这些
      在同一时间。

    同时放置水平和垂直分割线的例子。

    res/drawable/divider.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android"> <size     android:width="8dp"     android:height="12dp" /> <solid android:color="#44A444" /> </shape> 

    res/layout/content_main.xml

    <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:alignContent="flex_start" app:alignItems="flex_start" app:flexWrap="wrap" app:showDivider="beginning|middle" app:dividerDrawable="@drawable/divider" >  <TextView     style="@style/FlexItem"     android:layout_width="220dp"     android:layout_height="80dp"     android:text="1" /> <TextView     style="@style/FlexItem"     android:layout_width="120dp"     android:layout_height="80dp"     android:text="2" /> <TextView     style="@style/FlexItem"     android:layout_width="160dp"     android:layout_height="80dp"     android:text="3" /> <TextView     style="@style/FlexItem"     android:layout_width="80dp"     android:layout_height="80dp"     android:text="4" /> <TextView     style="@style/FlexItem"     android:layout_width="100dp"     android:layout_height="80dp"     android:text="5" />

  • layout_order (integer)

    • 这个属性能改变子views布局的顺序,默认子view显示放置相同的顺序跟他们在XML声明的一样。

  • layout_flexGrow (float)

    • 这个属性决定了子view将增大多少,如果可分配的空间还有多余时根据相对于其他的flex的同一行的items,
      如果一个flex的item 有一个正数layout_flexGrow的值,在flex行中这个item将占据剩余的部分。如果相同
      的flex一行有多个flex items有layout_flexGrow正数的值,剩下的自由的空间分配根据他们声明的layout_flexGrow 值得比例。(类似 LinearLayoutlayout_weight属性)如果不指定,这个值默认设置为0

  • layout_flexShrink (float)

    • 这个属性决定了子view将缩小多少,如果可分配的空间不足时的时候相对于其他的flex的同一行的items.
      如果没有指定,默认值设置为1

  • layout_alignSelf

    • 这个属性决定了交叉轴(垂直于主轴)的对齐方式。在同方向对齐可以根据父的alignItems决定,但是如果这个属性设置了
      其他的属性除了auto,交叉轴的对齐将会被子view重写,可能的值:
    • auto (default)
    • flex_start
    • flex_end
    • center
    • baseline
    • stretch

  • layout_flexBasisPercent (fraction)

    • 初始的flex的item长度用一个分数的格式相对于他的父长度,这个子view的初始主要大小尝试扩展根据指定的分数相对于父的
      主要大小。
      如果这个值设置了,从layout_width(或者 layout_height)指定的长度会被重写通过这个分数计算的到的值。
      这个属性仅当父的长度明确时才有效(MeasureSpec mode isMeasureSpec.EXACTLY)。默认值是-1,以为着不设置。

  • layout_minWidth / layout_minHeight (dimension)

    • 这些属性为FlexboxLayout的孩子设置了最小尺寸限制,一个孩子,不能收缩小于这些属性的值(变化的基础上flexDirection属性是指哪个属性将大小限制强加于主轴),不管layout_flexShrink属性

  • layout_maxWidth / layout_maxHeight (dimension)

    • 这些属性为FlexboxLayout的孩子设置了最大尺寸限制,一个孩子,不能伸展大于这些属性的值(变化的基础上flexDirection属性是指哪个属性将大小限制强加于主轴),不管layout_flexGrow属性

  • layout_wrapBefore (boolean)

    • 这个属性强制一个flex线包装,默认值是“false”。也就是说,如果这个被设置为“true”
      flex项目,这个项目将成为flex系列的第一个项目。(包装情况不考虑在之前的flex系列中处理的flex项目)
      如果“flexwrap”属性设置为“nowrap”,则忽略该属性。在原来的CSS灵活框模块中没有定义等效属性规范,
      但是拥有这个属性对于Android开发人员是很有用的。例如,压平在构建网格状布局时的布局,或者是开发人
      员想要的情况为了使一个新的flex线与前一个的语义不同,等等。

Others

这个库尝试尽可能跟原
Flexible Box specification 功能相同,
但是由于某些原因,比如指定属性的方式在这两者之间是不一样的
CSS和Android XML,与原始规范有一些已知的区别

(1) 没有与 flex-flow
等效的属性
* 因为flex-flow是设置flex-directionflex-wrap属性的缩写,
从单个属性中指定两个属性在Android中是不实用的。

(2) 没有flex 等效属性
* 同样的,flex 是设置flex-growflex-shrinkflex-basis的缩写,
从单个属性中指定这些属性是不实际的。

(3)layout_flexBasisPercent被引入,而不是
flexBasis
* 本库中的layout_flexBasisPercent和CSS中的flex-basis属性都被用于
确定单个flex项目的初始长度。flex-basis属性接受宽度
诸如1em10pxcontent等值,以及诸如此类的百分比值
“10%”和“30%”。layout_flexBasisPercent只接受百分比值。
但是,指定初始固定宽度值可以通过指定宽度(或高度)值来完成
layout_width(或layout_height,取决于flexDirection)。同时,相同的
layout_width(或layout_height)中指定”wrap_content”来实现效果。
开发人员想要达到与 ‘content’相同的效果。因此,只有layout_flexBasisPercent
接受百分比值,这不能通过ayout_width(或layout_height)来简单完成

(4) layout_wrapBefore 已经介绍.
* 在CSS灵活的Box模块规范中不存在等价的属性,
但正如上面所解释的,Android开发者将会受益于拥有这个属性
当包装发生时,更多的控制。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!