React Native Flex布局

1 flex布局基本概念

flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。采用flex布局的元素,称为flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为flex项目(flex item),简称"项目"。如下图所示:

image

容器默认存在两根轴:主轴(main axis)和交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

Flex布局与Android的线性布局(LinearLayout)有点类似,都可以设置布局方向,对齐方式,以及项目的布局占位权重,区别是flex容器中项目分布的总长度超出屏幕宽度,超出的那部分项目不可见,项目不会变形,或者可以设置flexWrap属性,让容器可以分行布局,所有项目都能显示出来。

2 flex基本属性

flex属性声明在:/node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js

  // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
  flexDirection: ReactPropTypes.oneOf([
    'row',
    'column'
  ]),

  // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
  flexWrap: ReactPropTypes.oneOf([
    'wrap',
    'nowrap'
  ]),

  // How to align children in the main direction
  // https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
  justifyContent: ReactPropTypes.oneOf([
    'flex-start',
    'flex-end',
    'center',
    'space-between',
    'space-around'
  ]),

  // How to align children in the cross direction
  // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
  alignItems: ReactPropTypes.oneOf([
    'flex-start',
    'flex-end',
    'center',
    'stretch'
  ]),

  // How to align the element in the cross direction
  // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
  alignSelf: ReactPropTypes.oneOf([
    'auto',
    'flex-start',
    'flex-end',
    'center',
    'stretch'
  ]),

  // https://developer.mozilla.org/en-US/docs/Web/CSS/flex
  flex: ReactPropTypes.number,

由上述代码,我们可以看到flex的属性并不多,而且很好记忆,以下将会一一介绍

flex属性可以分为容器属性和项目属性
其中容器属性包括:flexDirectionjustifyContentalignItemsflexWrap

项目属性包括:flexalignSelf

以下介绍会使用到一些代码和图片,先定义两个简单组件,方便理解

//定义一个默认半径为20,颜色为#527fe4的圆组件
var Circle = React.createClass({
  render : function(){
    var size = this.props.size || 20;
    var color = this.props.color || '#527fe4';
    return <View style={{backgroundColor:color,borderRadius:size/2,height:size,width:size,margin:1}}/>
  },
});

//定义一个放置标题和项目的容器,传入的value属性将会是需要介绍的flex属性
var Value = React.createClass({
  render : function(){
    var value = 
      <View>
        <Text style={styles.valueText}>{this.props.title}</Text>
        <View style={[styles.valueContainer,this.props.value]}>
          {this.props.children}
        </View>
      </View>;
    return value;
  },
});

//定义一个数组放置5个圆
var children = [<Circle/>,<Circle/>,<Circle/>,<Circle/>,<Circle/>];

2.1 容器属性

  1. flexDirection:布局方向,决定主轴的方向,默认值是column,即纵向布局

    |值    |描述                 |
    |------|--------------------|
    |row   |横向布局,主轴为水平方向|
    |column|纵向布局,主轴为竖直方向|

    row:横向布局
    代码:

    <Value title='row' value={{flexDirection:'row'}}>
        {children}
    </Value>

    视图:

    column:纵向布局
    代码:

    <Value title='column' value={{flexDirection:'column'}}>
        {children}
    </Value>

    视图:

  2. justifyContent:主轴方向对齐方式,默认值是flex-start,即主轴的开端

    |值           | 描述                   |
    |-------------|-----------------------|
    |flex-start   | 主轴开端                |
    |center       | 居中                   |
    |flex-end     | 主轴末端                |
    |space-between| 项目与项目之间插入相等空隙 |
    |space-around | 项目两旁插入相等空隙      |

    flex-start:主轴开端
    代码:

    <Value title='flex-start' value={{flexDirection:'row', justifyContent:'flex-start'}}>
        {children}
    </Value>

    视图:

    center:主轴的中间位置
    代码:

    <Value title='center' value={{flexDirection:'row',justifyContent:'center'}}>
        {children}
    </Value>

    视图:

    flex-end:主轴的末端位置
    代码:

    <Value title='flex-end' value={{flexDirection:'row',justifyContent:'flex-end'}}>
        {children}
    </Value>

    视图:

    space-between:项目与项目之间插入相同距离的空隙
    代码:

    <Value title='space-between' value={{flexDirection:'row',justifyContent:'space-between'}}>
        {children}
    </Value>

    视图:

    space-around:项目两旁插入相同距离的空隙
    代码:

    <Value title='space-around' value={{flexDirection:'row',justifyContent:'space-around'}}>
        {children}
    </Value>

    视图:

  3. alignItems:交叉轴方向对齐方式,默认值flex-start,即交叉轴开端

    |值        | 描述      |
    |----------|----------|
    |flex-start| 交叉轴开端 |
    |center    | 交叉轴居中 |
    |flex-end  | 交叉轴末端 |

    flex-start:交叉轴开端

    center:交叉轴的中间位置

    flex-end:交叉轴的末端位置

  4. flexWrap:包含内容,默认值是nowrap,不包裹所有内容

    |值    |描述                                                     |
    |------|--------------------------------------------------------|
    |nowrap|项目沿主轴方向布局,超出容器长度的部分不可见                    |
    |wrap  |项目沿主轴布局所需长度大于容器总长度时,分行布局,所有项目内容都可见|

    nowrap:不包裹内容
    代码:

    <Value title='nowrap' value={{flexWrap:'nowrap',flexDirection:'row'}}>
          {children}{children}{children}{children}
    </Value>

    视图:

    wrap:包裹内容
    代码:

    <Value title='wrap' value={{flexWrap:'wrap',flexDirection:'row'}}>
          {children}{children}{children}{children}
    </Value>

    视图:

2.2 项目属性

  1. flex:布局权重

    |值 |描述       |
    |---|----------|
    |>=0|项目占位权重|

    1:0:flex=0的项目占用空间仅为内容所需空间,flex=1的项目会占据其余所有空间
    代码:

    <Value title='1:0' value={{flexDirection:'row'}}>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'red',fontSize:20,paddingHorizontal:10}}>flex=1</Text>
        <Text style={{color:'white',textAlign:'center',backgroundColor:'yellow',fontSize:20,paddingHorizontal:10}}>flex=0</Text>
    </Value>

    2:1
    代码:

    <Value title='2:1' value={{flexDirection:'row'}}>
        <Text style={{color:'white',flex:2,textAlign:'center',backgroundColor:'blue',fontSize:20}}>flex=2</Text>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'green',fontSize:20}}>flex=1</Text>
    </Value>

    1:1:1:1
    代码:

    <Value title='1:1:1:1' value={{flexDirection:'row'}}>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'red',fontSize:20}}>flex=1</Text>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'yellow',fontSize:20}}>flex=1</Text>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'blue',fontSize:20}}>flex=1</Text>
        <Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'green',fontSize:20}}>flex=1</Text>
    </Value>

  2. alignSelf:项目交叉轴方向自身对齐方式

    |值        |描述|
    |----------|---|
    |flex-start|开端|
    |center    |居中|
    |flex-end  |末端|

    代码:

    <Value title='alignSelf' value={{flexDirection:'row',height:30,alignItems:'center'}}>
          <View style={{alignSelf:'flex-start'}}>
            <Circle/>
          </View>
          <View style={{alignSelf:'flex-end'}}>
            <Circle/>
          </View>
          <View style={{alignSelf:'flex-start'}}>
            <Circle/>
          </View>
          <View style={{alignSelf:'flex-end'}}>
            <Circle/>
          </View>
          <View style={{alignSelf:'flex-start'}}>
            <Circle/>
          </View>
    </Value>

    视图:

3 Layout的其他属性

layout除了flex属性之外,当然还有其他属性,同样声明在:/node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js

  width: ReactPropTypes.number,
  height: ReactPropTypes.number,
  top: ReactPropTypes.number,
  left: ReactPropTypes.number,
  right: ReactPropTypes.number,
  bottom: ReactPropTypes.number,
  margin: ReactPropTypes.number,
  marginVertical: ReactPropTypes.number,
  marginHorizontal: ReactPropTypes.number,
  marginTop: ReactPropTypes.number,
  marginBottom: ReactPropTypes.number,
  marginLeft: ReactPropTypes.number,
  marginRight: ReactPropTypes.number,
  padding: ReactPropTypes.number,
  paddingVertical: ReactPropTypes.number,
  paddingHorizontal: ReactPropTypes.number,
  paddingTop: ReactPropTypes.number,
  paddingBottom: ReactPropTypes.number,
  paddingLeft: ReactPropTypes.number,
  paddingRight: ReactPropTypes.number,
  borderWidth: ReactPropTypes.number,
  borderTopWidth: ReactPropTypes.number,
  borderRightWidth: ReactPropTypes.number,
  borderBottomWidth: ReactPropTypes.number,
  borderLeftWidth: ReactPropTypes.number,

  position: ReactPropTypes.oneOf([
    'absolute',
    'relative'
  ]),

|属性                  |类型  |描述                                |
|---------------------|------|-----------------------------------|
|width                |number|容器或者项目的宽度                    |
|height               |number|容器或者项目的高度                    |
|top,bottom,left,right|number|在父容器的上下左右偏移量               |
|margin               |number|留边,留边的空间不属于容器或者项目自身空间|
|marginHorizontal     |number|水平方向留边                         |
|marginVertical       |number|垂直方向留边                         |
|padding              |number|填充,填充的空间输入容器或者项目自身空间  |
|paddingHorizontal    |number|水平方向填充                         |
|paddingVertical      |number|垂直方向填充                         |
|borderWidth          |number|边界宽度                            |
|position             |enum  |位置方式:absolute与relative         |

position:默认值为relative

|值      |描述   |
|--------|------|
|absolute|绝对布局|
|relative|相对布局|

react的默认位置方式是relative,项目是一个接一个排列下去的,absolute为绝对布局,一般会与left和top属性一起使用。有时候我们需要实现某些项目重叠起来,absolute属性就能发挥作用了,例如下图:

react的基本组件暂时不支持以图片作为背景,所以这里的的转入是一个文本组件,而红色的圆形是一个图片组件,在IOS里面组件也可以作为容器,图片可以正常显示,但是在Android里面,可能存在些问题,如果使用组件作为容器都会出现图片变得好奇怪,所以就可以absoulte来解决问题了。代码如下:

<View style={{width:80,height:80,alignItems:'center',justifyContent:'center'}}>
    <Image style={{position:'absolute',left:0,top:0,resizeMode:'contain',width:80,height:80}} source={require('image!finance_usercenter_ic_into')}/>
	<Text style={{width:80,textAlign:'center',color:'white',fontSize:16}}>转入</Text>
</View>

这里的View跟Android的View有点不一样,View是可以作为容器也可以作为项目,View作为容器还有其他很多属性,例如backgroundColor,borderWidth,borderColor,opacity等等,这里不一一介绍。

4 布局的尺寸说明

react native的宽高是不需要带单位的,那些widthheightpaddingmargin的赋值都直接是数字的,当你设定width:10,在IOS的话就是设置了10pt宽度,而在Android上面是10dp,在做项目时,辛勤的美工会帮我们标出所有UI控件的宽,高,边距等等,他们用的单位也是dp,所以赋值style中宽高时,直接填入数字即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
React Native弹性布局是一种基于Flexbox布局模型的布局方式,它可以让你更轻松地创建具有弹性的用户界面。Flexbox是一种用于在屏幕上分配空间的CSS3布局模型,它可以将一个容器中的子元素沿着一个主轴和交叉轴进行对齐和排列。在React Native中,弹性布局可以让你使用一系列简单的布局属性来指定容器中的子元素如何进行布局。 具体而言,React Native中弹性布局有以下常用属性: - `flex`:定义一个元素的伸缩能力,默认值为0,即不伸缩。 - `flexDirection`:定义元素在容器中的排列方向,可选值包括`row`(水平方向)、`column`(竖直方向)、`row-reverse`(反向水平方向)和`column-reverse`(反向竖直方向)。 - `justifyContent`:定义元素在主轴上的对齐方式,可选值包括`flex-start`、`center`、`flex-end`、`space-between`(两端对齐)和`space-around`(各个元素之间留有空隙)。 - `alignItems`:定义元素在交叉轴上的对齐方式,可选值包括`flex-start`、`center`、`flex-end`、`stretch`(默认值,拉伸元素以填充交叉轴)和`baseline`(让元素按照它们的基线对齐)。 下面是一个使用弹性布局实现水平居中和竖直居中的例子: ```javascript import React from 'react'; import { View, StyleSheet } from 'react-native'; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, box: { width: 100, height: 100, backgroundColor: 'red', }, }); const App = () => { return ( <View style={styles.container}> <View style={styles.box} /> </View> ); }; export default App; ``` 这里的`container`使用了弹性布局,并且使用了`justifyContent`和`alignItems`来实现水平和竖直居中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值