React Native移动开发实战
上QQ阅读APP看书,第一时间看更新

3.1 FlexBox布局

FlexBox是flexible box的缩写,译为“弹性盒布局”, FlexBox是React Native开发中必不可少的页面组成部分,下面针对FlexBox的基础属性和实例做简单的讲解。

3.1.1 FlexBox简介

做过前端开发的人都知道,传统的页面布局基于盒子模型而设计,主要依赖于定位属性、流动属性和显示属性。而处理一些伸缩性的布局,传统的盒子模型处理起来很麻烦。于是在2009年,由W3C组织提出了一种全新的布局方案,即Flex布局方案。该布局可以解决传统页面无法伸缩的问题,相比传统的盒子布局,FlexBox更加灵活。

引入FlexBox布局模型的目的是提供一种更加有效的方式来对一个容器中的条目进行排列、对齐和空白空间分配。即便容器中条目的尺寸未知或是动态变化的,FlexBox布局模型也能正常工作。在FlexBox布局模型中,容器会根据布局的需要,调整其中包含的条目的尺寸和顺序来恰当地填充所有可用的空间,当容器的尺寸由于屏幕大小或窗口尺寸发生变化时,其中包含的条目也会动态地调整。

在FlexBox的官网:http://caniuse.com中,读者可以查看目前市场上大部分浏览器对FlexBox的支持情况,如图3-1所示。

图3-1 浏览器对FlexBox的支持情况

FlexBox主要由伸缩容器和伸缩项目组成,[flex-container]定义一个伸缩容器,伸缩容器中的每一个子元素都是一个伸缩项目。简单来说,Flexbox就是为了伸缩容器内伸缩项目的布局而设计的。

3.1.2 FlexBox布局模型

FlexBox布局的容器(flex container)指采用了FlexBox布局的DOM元素,而FlexBox布局的条目(flex item)指容器中包含的子DOM元素,如图3-2所示。

图3-2 FlexBox布局模型

由上图可知,FlexBox布局主要由两个互相垂直的坐标轴组成:主轴(main axis)和交叉轴(cross axis)。主轴并不一定为水平方向的x轴,交叉轴也不一定为垂直方向的y轴。在使用时,通过CSS属性声明首先定义主轴的方向,则交叉轴的方向也相应确定下来。容器中的条目可以排列成单行或多行。主轴确定了容器中每一行上条目的排列方向,而交叉轴则确定行本身的排列方向。在实际应用中,可以根据不同的页面设计要求来确定合适的主轴方向。

确定主轴和交叉轴的方向之后,还需要确定它们各自的排列方向。对于水平方向上的轴,可以从左到右或从右到左来排列;对于垂直方向上的轴,则可以从上到下或从下到上来排列。对于主轴来说,排列条目的起始和结束位置分别称为主轴起始(main start)和主轴结束(main end),对于交叉轴来说,排列行的起始和结束位置分别称为交叉轴起始(cross start)和交叉轴结束(cross end)。在容器进行布局时,在每一行中会把其中的条目从主轴起始位置开始,依次排列到主轴结束位置;而当容器中存在多行时,会把每一行从交叉轴起始位置开始,依次排列到交叉轴结束位置。

FlexBox布局中的条目有两个尺寸:主轴尺寸和交叉轴尺寸,分别对应其DOM元素在主轴和交叉轴上的大小。如果主轴是水平方向,则主轴尺寸和交叉轴尺寸分别对应于DOM元素的宽度和高度;如果主轴是垂直方向,则主轴尺寸和交叉轴尺寸要反过来。

3.1.3 FlexBox布局属性

FlexBox布局的常用属性有:

· display-flex

· flex-direction

· flex-warp

· flex-flow

· justify-content

· align-items

· align-content

display-flex

本属性用来指定元素是否使用弹性盒布局。当使用FlexBox布局的时候,需要先给父容器的display值定位flex(块级)或者inline-flex(行内级)。其语法为:

        display:flex | inline-flex

下面简要介绍下这两个属性的含义。

flex用于块级伸缩属性。示例代码如下:

        .flex-container {
            display: flex;
            …
        }

inline-flex用于行内伸缩属性。示例代码如下:

        .flex-container {
            display:inline- flex;
            …
        }

flex-direction

本属性用来控制伸缩容器中主轴的方向,同时也决定了伸缩项目的方向。常用的属性如下所示。

· flex-direction:row:默认值,主轴的方向和正常的方向一致,从左到右排列。

· flex-direction:row-reverse:和row的方向相反,从右到左排列。

· flex-direction:column:从上到下排列。

· flex-direction:column-reverse:从下到上排列。

示例代码如下:

        .flex-container {
            flex-direction: row;
            …
        }

flex-direction属性常见展示效果如图3-3所示。

图3-3 flex-direction属性效果

flex-wrap

本属性用来控制伸缩容器是单行还是多行,也决定侧轴方向。常见的属性值如下所示。

· flex-wrap:nowrap:默认值,伸缩容器单行显示。

· flex-wrap:wrap:伸缩容器多行显示;排列顺序由上到下排列。

· flex-wrap:wrap-reverse:伸缩容器多行显示,排列顺序由下到上排列。

flex-wrap属性常见展示效果如图3-4所示。

图3-4 flex-wrap属性效果

flex-flow

本属性是flex-direction(主轴方向)和flex-wrap(侧轴方向)的缩写。这两个属性决定了伸缩容器的主轴与侧轴,默认值为row nowrap。其语法为:

        flex-flow:[flex-direction][flex-wrap];

示例代码如下:

        flex-flow: row wrap;

flex-flow属性常见展示效果如图3-5所示。

图3-5 flex-flow属性效果

justify-content

本属性用来定义伸缩项目在主轴上的对齐方式。当一行上的所有伸缩项目都不能伸缩或可伸缩但是已经达到其最大长度时,本属性会对多余的空间进行分配。

其常见的属性如下所示。

· justify-content:flex-start:伸缩项目以主轴的起始位置开始对齐,后面的每个元素紧挨着前一个元素对齐。

· justify-content:flex-end:伸缩项目以主轴的结束位置对齐,前面的每个元素紧挨着后一个元素对齐。

· justify-content:center:伸缩项目相互对齐并在主轴上处于居中,并且第一个元素到主轴起点的距离等于最后一个元素到主轴终点的位置。

· justify-content:space-between:伸缩项目平均的分配在主轴上,第一个元素和主轴的起点紧挨,最后一个元素和主轴上终点紧挨,中间剩下的伸缩项目进行平分。

· justify-content:space-around:伸缩项目平均的分布在主轴上,第一个元素到主轴起点距离和最后一个元素到主轴终点的距离相等,且等于中间元素两两的间距的一半,完美地平均分配。

示例代码如下:

        <View
        style={ {justifyContent:'center', flexDirection:'row', backgroundColor:"darkgray",
    marginTop:20}}>
        </View>

just-content属性常见展示效果如图3-6所示。

图3-6 justify-content属性效果

align-items

本属性用来定义伸缩项目在侧轴的对齐方式。flex-directon和flex-wrap是一对,justify-content和align-items是一对。前者分别定义主轴和侧轴的方向,后者分别定义主轴和侧轴中项目的对齐方式。其常见的属性如下所示。

· align-items:flex-start:伸缩项目在侧轴起点边的外边距紧靠该行在侧轴起点的边。

· align-items:flex-end:伸缩项目在侧轴终点边的外边距靠该行在侧轴终点的边。

· align-items:center:伸缩项目的外边距在侧轴上居中放置。

· align-items:baseline:如果伸缩项目的行内轴与侧轴为同一条,则该值与[flex-start]等效。

· align-items:stretch:伸缩项目拉伸填充整个伸缩容器。

align-items属性常见效果如图3-7所示。

图3-7 align-items属性效果

align-content

本属性用来调整伸缩行在伸缩容器里的对齐方式。其作用类似于justify-content,只不过justify-content表示的是主轴方向上对齐行中的条目。本属性在只有一行的伸缩容器上没有效果。

其语法为:

        align-content: flex-start || flex-end || center || space-between ||
        space-around || stretch;

常见的属性如下所示。

· flex-start:元素沿着容器的交叉轴起始位置对齐。

· flex-end:元素沿着容器的交叉轴的结束位置对齐,和flex-start相反。

· flex-center:元素沿着容器的交叉轴的中央位置对齐,在交叉轴起始方向和结束方向上留有同样大小的空白空间。

· space-between:元素在容器中均匀分布。第一行与起始位置保持对齐,最后一行与结束位置保持对齐,空白空间在行之间平均分配。

· space-around:本属性类似于space-between,不同的是第一行条目和最后一个行目与容器行的边界之间同样存在空白空间,而空白空间的尺寸是行目之间的空白空间的尺寸的一半。

· stretch:元素被拉伸来占满剩余的空间。

align-content属性常见的展示效果如图3-8所示。

图3-8 align-content属性

3.1.4 FlexBox伸缩项目属性

伸缩项目属性主要包含如下3个子属性。

· order

· flex(flex-grow、flex-shrink、flex-basis)

· align-self

order

本属性主要用来定义项目的排列顺序,数值越小越靠前,默认值为0。

例如,一个container中有4个box,我们想让box4第一个显示,box1为最后一个显示。那么我们只需要将box4设置为[order:-1; ]既可。代码示例如下:

        <style>
        .container{
            display: flex;
          }
          .box1{
            order:1;
          }
          .box4{
            order:-1;
          }
        </style>
        <div class="container">
          <div class="box1">1</div>
          <div class="box2">2</div>
          <div class="box3">3</div>
          <div class="box4">4</div>
        </div>

order属性代码运行效果如图3-9所示。

图3-9 order属性效果

flex

本属性主要用来指定可伸缩长度,主要由扩展比例属性(flex-grow)、收缩比例属性(flow-shrink)和伸缩基准值属性(flex-basis)3个属性组成。其语法为:

        flex:none | [ <'flex-grow'> ? <'flew-shrink'> || <'flow-basis'>]

· flex-basis:本属性用来定义伸缩项目的基准值。默认是auto,即根据可伸缩比例计算出剩余空间的分布之前,伸缩项目主轴长度为起始数值。其语法为:

        flex- basis:length|auto

· flex-grow:本属性用来定义伸缩项目的放大比例,即用来决定伸缩容器剩余空间按比例应扩展多少空间。

默认值为0,即如果存在剩余空间,也不放大。如果flex-grow设置为1,即将每一个伸缩空间设置为一个大小相等的剩余空间。

· flex-shrink:本属性用来定义伸缩项目的缩放比例,即用来决定伸缩容器里其他伸缩项目的收缩空间比例。在收缩的时候收缩比例会以[flex-basis]伸缩基准值加权。

align-self

本属性用来覆写设置单独的伸缩项目在交叉轴上的对齐方式。该属性是用来覆盖伸缩容器属性align-items对每一行的对齐方式。也就是说,在默认的情况下这两个值是相等的。其语法为:

        align-self: auto | flex-start | flex-end | center | baseline | stretch

示例代码如下:

        .flex-container {
            display: flex;
            …
        }
        .item{
            align-self:auto
        }

3.1.5 FlexBox在React Native中的应用

React Native通过引入FlexBox的布局引擎,可以在所有移动平台上实现了一致的跨平台样式和布局方案。

在React Native中,FlexBox布局目前支持的属性有如下6个:

· flex

· flexDirection

· alignSelf

· alignItems

· justifyContent

· flexWrap

flex

本属性与CSS中的flex一样,用来指定元素是否使用弹性盒布局。不过需要注意的是,属性值大于0才可伸缩。其语法如下:

        flex: number

flexDirection

本属性与CSS中的flex- direction一样,用来指定元素的伸缩方向。row表示横向伸缩,column表示纵向伸缩。其语法如下:

        flexDirection: row | column

alignSelf

本属性与CSS中的align-self一样,用来设置单独的伸缩项目在交叉轴上的对齐方式。其语法如下:

        flexSelf: flex-start | flex-end | center | auto | stretch

alignItems

本属性与CSS中的align-items一样,用来设置伸缩项目在侧轴的对齐方式。其语法如下:

        flexItems: flex-start | flex-end | center | stretch

flexWrap

本属性与CSS中的flex-wrap一样,用来控制伸缩项目是单行还是多行展示。其语法如下:

        flexWrap: wrap | nowrap

justifyContent

本属性与CSS中的justify-Content一样,用来控制伸缩项目在主轴上的对齐方式。其语法如下:

        justifyContent: flex-start | flex-end | center | space-between | space-around

3.1.6 FlexBox综合实例

下面我们将通过示例程序来加强对FlexBox布局的理解。其最终的界面如图3-10所示。

图3-10 FlexBox综合实例

图3-10的界面主要由两部分组成,HTML和CSS样式文件,而在排版的时候使用FlexBox替换百分比布局。

HTML核心代码如下:

    <div class="main">
      <div class="header common">
        <div class="logo"></div>
        <div class="title">Flexbox</div>
      </div>

      <div class="main-center">
        <div class="item left common">
            <a href="#">专栏</a>
        </div>
        <div class="item right common">
            <a href="#">通告</a>
        </div>
      </div>

      <div class="footer common">
        <span>Copyright © <strong>xiangzhihong</strong>
     All Right Reserved</span>
      </div>
    </div>

CSS样式文件代码如下:

    body {
      background-color: #333;
      font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
      font-size: 100%;
    }

    .footer {
      position: relative;
      width: 100%;
      height: 160px;
      background-color: #345AA3;
      color: #fff;
      font-size: 100%;
      text-align: center;
      -Webkit-flex-direction: column;
      flex-direction: column;
    }

    .main-center .left,
    .main-center .right {
      -Webkit-flex-direction: column;
      flex-direction: column;
    }
        .main-center img {
          width: 80px;
        }

        .footer {
          background-color: #999;
          color: #666;
          font-size: 100%;
        }

        .main-center,
        .common {
          display: -Webkit-flex;
          display: -moz-flex;
          display: -ms-flex;
          display: flex;
          -Webkit-justify-content: center;
          justify-content: center;
          -Webkit-align-items: center;
          align-items: center;
        }

        .item {
          width: 48%;
          margin: 1% 0;
          color: #fff;
          min-height: 160px;
        }

        .left {
          background-color: #913E8E;
        }

        .right {
          background-color: #00B1BD;
        }

        .userface {
          width: 120px;
        }