相关文章

React Native探索系列

前言

在Android开发中我们有很多种布局,比如LinearLayout和RelativeLayout,同样在React Native也有它的布局,这个布局就是Flexbox布局。在CSS、React Native和Android等都有它的身影。这一篇文章,我们就通过各种小例子来掌握React Native中的Flexbox布局。

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),简称项目。如下图所示。

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

2.Flexbox容器属性

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

  • flexDirection
  • justifyContent
  • alignItems
  • alignContent
  • flexWrap

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

flexDirection

flexDirection属性可以决定主轴的方向(即项目的排列方向),它有以下取值:

  • 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相关原创技术干货。

扫一扫下方二维码或者长按识别二维码,即可关注。

React Native探索(四)Flexbox布局详解的更多相关文章

  1. 3、手把手教React Native实战之flexbox布局

    flexbox是Flexible Box的缩写,弹性盒子布局  主流的浏览器都支持 flexbox布局是伸缩容器(container)和伸缩项目(item)组成 Flexbox布局的主体思想是元素可以 ...

  2. 4、手把手教React Native实战之flexbox布局(伸缩属性)

    ###伸缩项目的属性 1.order 定义项目的排列顺序,数值越小,排列越靠前,默认值为0,语法为:order:整数值 2.flex-grow 定义伸缩项目的放大比例,默认值为0,即表示如果存在剩余空 ...

  3. React Native 入门到原理(详解)

    抛砖引玉(帮你更好的去理解怎么产生的 能做什么) 砖一.动态配置 由于 AppStore 审核周期的限制,如何动态的更改 app 成为了永恒的话题.无论采用何种方式,我们的流程总是可以归结为以下三部曲 ...

  4. React Native入门 认识Flexbox布局

    Flexbox布局是由W3C在09年提出的在Web端取代CSS盒子模型的一种布局方式. ReactNative实现了Flexbox布局的大部分功能. Flexbox布局所使用的属性,基本可以分为两大类 ...

  5. Flexbox布局详解

    弹性框布局 (flexbox) 添加了级联样式表级别 2 修订版 1 (CSS2.1) 中定义的四个基本布局模式:块布局.内联布局.表格布局和定位布局.使用弹性框布局功能,你可以更加轻松地设计复杂网页 ...

  6. Android学习之基础知识六—Android四种布局详解

    一.Android基本布局 布局是一种可以放置多个控件的容器,它可以按照一定规律调整内部控件的位置,而且布局内部除了可以放置控件外,还可以放置布局,实现多层布局嵌套.布局和控件.布局和布局之间的关系如 ...

  7. React Native之ScrollView控件详解

    概述 ScrollView在Android和ios原生开发中都比较常见,是一个 滚动视图控件.在RN开发中,系统也给我们提供了这么一个控件.不过在RN开发中 ,使用ScrollView必须有一个确定的 ...

  8. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  9. Android布局详解之一:FrameLayout

      原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...

随机推荐

  1. Python基础学习之 函数

    阅读目录 第一篇:  函数初识 第二篇:  函数命名空间 作用域 闭包 第三篇:  装饰器 第四篇:  装饰器 面试题错误点 第五篇:  迭代器生成器 第六篇:  生成器进阶 第七篇:  递归 第八篇 ...

  2. beego——参数配置

    beego目前支持INI.XML.JSON.YAML格式的配置文件解析,但是默认采用了INI格式解析,用户可以通过简单的配置就可以获得很大的灵活性. 一.默认配置解析 beego 默认会解析当前应用下 ...

  3. SHELL —— BASH环境

    一 .什么是SHELL shell一般代表两个层面的意思,一个是命令解释器,比如BASH,另外一个就是shell脚本.本节我们站在命令解释器的角度来阐述shell 二 .命令的优先级 命令分为: == ...

  4. 【转】Linux 下取进程占用 cpu/内存 最高的前10个进程

    # Linux 下 取进程占用 cpu 最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head # linux 下 取进程占用内存 ...

  5. C++中int转为char 以及int 转为string和string 转int和字符串的split

    1.对于int 转为char 直接上代码: 正确做法: void toChar(int b) { char u; ]; _itoa( b, buffer, ); //正确解法一 u = buffer[ ...

  6. 解析Linux系统的平均负载概念

    一.什么是系统平均负载(Load average)? 在Linux系统中,uptime.w.top等命令都会有系统平均负载load average的输出,那么什么是系统平均负载呢?系统平均负载被定义为 ...

  7. ThinkPHP开发博客系统笔记之二

    1. 登陆验证码 当用户登陆的时候我们希望也弹出验证码,有两种方法可以实现:一是再增加一个弹出验证码的dialog,二是和注册共用一个验证码dialog.第一种方法有大量重复代码,所以我们使用第二种方 ...

  8. centos 安装 谷歌BBR

    使用root用户登录,运行以下命令: wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh  ...

  9. 在eclipse下使用maven的配置

    1 2 3 4 5 6 7 8 public class Shifty {     public static void main(String[] args) {         int i = 0 ...

  10. SQL优化器执行过程之逻辑算子

    我们提到了两种SQL优化器,分别是RBO和CBO.那么无论是RBO,还是CBO都包含了一系列优化规则,这些优化规则可以对关系表达式进行等价转换,从而寻找最优的执行计划. 那么常见的优化规则就包括: 列 ...