React Native 探索(四)Flexbox 布局详解

相关文章
React Native探索系列javascript

前言

在Android开发中咱们有不少种布局,好比LinearLayout和RelativeLayout,一样在React Native也有它的布局,这个布局就是Flexbox布局。在CSS、React Native和Android等都有它的身影。这一篇文章,咱们就经过各类小例子来掌握React Native中的Flexbox布局。html

1.Flexbox布局概述

Flexbox译为弹性布局(这里咱们简称Flex),是CSS的一种布局方案,能够简单、完整、响应式的实现各类页面布局。不仅是在CSS中应用,在React Native也使用了Flex,基本和CSS中的Flex相似。甚至在Android开发中咱们也会用到Flex,谷歌提供了基于Flex的FlexboxLayout,以便于处理复杂的布局,所以,学习Flex布局对于Android开发也是有帮助的。
采用Flex布局的元素,称为Flex容器(flex container),简称容器,它的全部子元素则是Flex容器的成员称为Flex项目(flex item),简称项目。以下图所示。java

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置叫作main start,结束位置叫作main end。类似的,交叉轴的开始位置叫作cross start,结束位置叫作cross end。项目默认沿主轴排列,它在主轴上的长度叫作main size,交叉轴上的长度叫作cross size。react

2.Flexbox容器属性

在CSS(React)中容器属性有6种,而在React Native中容器属性有5种,它们分别是:git

  • flexDirection
  • justifyContent
  • alignItems
  • alignContent
  • flexWrap

下面经过小例子来分别介绍这些Flexbox容器属性。github

flexDirection

flexDirection属性能够决定主轴的方向(即项目的排列方向),它有如下取值:react-native

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

咱们先将flexDirection设置为row,代码以下所示。微信

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{flex: 1, flexDirection: 'row', backgroundColor: 'ivory'}}>
                <View style={{width: 60, height: 60, backgroundColor: 'powderblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'skyblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'dodgerblue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

运行效果以下图所示。
布局

能够看出项目(子组件)是水平排列的,而且起点在左端。关于例子中的颜色设定能够查看官网文档。咱们也能够将flexDirection设置为row-reverse,来查看效果:
学习


能够看出Flex项目一样是水平排列的,只是起点在右端。

justifyContent

justifyContent属性用于定义项目在主轴上的对齐方式。它的取值有如下几种:

  • flex-start(默认值):项目与父容器左端对齐。
  • flex-end:项目与父容器右端对齐。
  • center:居中。
  • space-between: 两端对齐,而且项目间隔相等。
  • space-around:每一个项目的两侧间隔相等,所以,项目之间的间隔是项目与父容器边缘间隔的2倍。

咱们将justifyContent设置为flex-end,代码以下所示。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end', backgroundColor: 'ivory'}}>
                <View style={{width: 60, height: 60, backgroundColor: 'powderblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'skyblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'dodgerblue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

效果以下所示。

接下来咱们分别设置justifyContent为flex-startcenter,效果分别以下所示。

......

接下来咱们分别设置justifyContent为space-betweenspace-around来查看它们有什么区别,效果分别以下所示。

......

上面左图是设置了space-between,能够看出最左边和最右边的项目都和父容器没有间隔,而且项目之间的间隔是相等的。右图的是space-around,最左边和最右边的项目都和父容器有间隔,而且项目之间的间隔是项目与父容器的间隔的2倍。

alignItems

alignItems用于定义项目在交叉轴上的对齐方式。它的取值有如下几种:

  • flex-start:项目与父容器的顶部对齐。
  • flex-end:项目与父容器的底部对齐。
  • center:居中。
  • baseline :项目的第一行文字的基线对齐。
  • stretch:(默认值)若是项目未设置高度或者高度设为auto,项目将占满整个容器的高度,不然该取值不会生效。

将alignItems设置为flex-end,代码以下所示。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                justifyContent: 'center',
                alignItems: 'flex-end',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 60, height: 60, backgroundColor: 'powderblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'skyblue'}}/>
                <View style={{width: 60, height: 60, backgroundColor: 'dodgerblue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

效果以下图所示。

看到flex-end的效果,flex-start和center的效果也很容易知道。咱们接下来将alignItems设置为stretch,须要注意的是,当项目没有设置高度或者高度设为auto时,stretch才会生效。这里为了验证效果,将全部项目的高度设置为auto。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                justifyContent: 'center',
                alignItems: 'stretch',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 60, height: 'auto', backgroundColor: 'powderblue'}}/>
                <View style={{width: 60, height: 'auto', backgroundColor: 'skyblue'}}/>
                <View style={{width: 60, height: 'auto', backgroundColor: 'dodgerblue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

效果以下图所示。


能够看出,当alignItems设置为stretch时,项目会占满整个容器的高度。

alignContent

alignContent用于多行项目在交叉轴上的对齐方式。若是项目只有一行,该属性是不起做用的。它的取值有 flex-start 、flex-end 、 center 、space-between 、 space-around 和 stretch,只比justifyContent的取值多了一个stretch(默认值,含义和alignItems的stretch相似),alignContent的取值的含义和justifyContent的取值的含义相似,这里就不作举例了。

flexWrap

flexWrap用于设置若是一行排不下,如何换行。它的取值有如下几种:

  • nowrap(默认):不换行。
  • wrap:换行,第一行在上方。

咱们将flexWrap设置为wrap,代码以下所示。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                alignItems: 'flex-start',
                flexWrap: 'wrap',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 100, height: 60, backgroundColor: 'powderblue'}}/>
                <View style={{width: 100, height: 60, backgroundColor: 'skyblue'}}/>
                <View style={{width: 100, height: 60, backgroundColor: 'dodgerblue'}}/>
                <View style={{width: 100, height: 60, backgroundColor: 'blue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

效果以下所示。

3.Flexbox项目属性

在React Native中项目属性有不少中,具体的能够参考:Layout Props。这里介绍flexGrow、flexShrink、flexBasis、flex和alignSelf。

flexGrow

flexGrow属性定义项目的放大比例,默认为0,即若是存在剩余空间,也不放大。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                alignItems: 'flex-start',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 50, height: 50, flexGrow: 1, backgroundColor: 'powderblue'}}/>
                <View style={{width: 50, height: 50, flexGrow: 2, backgroundColor: 'skyblue'}}/>
                <View style={{width: 50, height: 50, flexGrow: 1, backgroundColor: 'dodgerblue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

咱们将第二个项目flexGrow设置为2,其余的项目flexGrow设置为1,这样第二个项目所占的剩余空间是其余项目的两倍。以下图所示。

flexShrink

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

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                alignItems: 'flex-start',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 120, height: 50, flexShrink: 1, backgroundColor: 'powderblue'}}/>
                <View style={{width: 120, height: 50, flexShrink: 0, backgroundColor: 'skyblue'}}/>
                <View style={{width: 120, height: 50, flexShrink: 1, backgroundColor: 'dodgerblue'}}/>
                <View style={{width: 120, height: 50, flexShrink: 1, backgroundColor: 'blue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

咱们将第二个项目的flexShrink设置为0,其余的项目都为1,这样当空间不足时,第二个项目不会缩小,以下图所示。

flexBasis

flexBasis属性定义了项目的初始宽度。它的默认值为auto,即项目的原本的宽度。咱们知道width也能够用来设置项目的宽度,若是项目同时设置了width和flexBasis,那么flexBasis会覆盖width的值。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                alignItems: 'flex-start',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 120, height: 50, flexBasis: 60, backgroundColor: 'powderblue'}}/>
                <View style={{width: 120, height: 50, backgroundColor: 'skyblue'}}/>
                <View style={{width: 120, height: 50, backgroundColor: 'dodgerblue'}}/>
                <View style={{width: 120, height: 50, backgroundColor: 'blue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

效果以下图所示。

flex

若是咱们每次都要设定flex-grow、flex-shrink和 flex-basis属性,显然有些麻烦,这时咱们能够用flex 属性,它是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性,默认值为0 1 auto,其中后两个属性可选。关于flex这里就不作举例了。

alignSelf

alignSelf属性和alignItems属性相似,只不过alignSelf做用于项目,它容许单个项目有与其余项目不同的对齐方式,而且覆盖alignItems属性。alignSelf默认值为为auto,表示继承父元素的alignItems属性,若是没有父元素,则等同于stretch。alignSelf有五种取值:auto、flex-start、flex-end、center、baseline和stretch,除了多了auto,其余的取值都和alignItems的取值含义同样。

import React, {Component} from 'react';
import {AppRegistry, View} from 'react-native';
class FlexDirection extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                alignItems: 'flex-start',
                backgroundColor: 'ivory'
            }}>
                <View style={{width: 60, height: 60, alignSelf: 'flex-end', backgroundColor: 'powderblue'}}/>
                <View style={{width: 60, height: 60, alignSelf: 'center', backgroundColor: 'skyblue'}}/>
                <View style={{width: 60, height: 'auto', alignSelf: 'stretch', backgroundColor: 'dodgerblue'}}/>
                <View style={{width: 60, height: 60, alignSelf: 'auto', backgroundColor: 'blue'}}/>
            </View>
        );
    }
}
AppRegistry.registerComponent('AwesomeProject', () => FlexDirection);复制代码

运行效果以下所示。

好了,关于Flexbox布局就讲到这,还有不少属性这里没有提到,好比:margin、padding、marginRight和maxWidth等等,这些属性咱们一看名字就知道它的做用(Android开发者角度),所以这里就很少介绍了,更多的属性请查阅官方文档

参考资料
官方文档
Flex 布局教程:语法篇---阮一峰
React-Native之flexbox布局篇


欢迎关注个人微信公众号,第一时间得到博客更新提醒,以及更多成体系的Android相关原创技术干货。
扫一扫下方二维码或者长按识别二维码,便可关注。

相关文章
相关标签/搜索