2.零基础学RN-Flexbox布局

2,038 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

1.背景

无论是移动开发还是Web开发中,布局技术都是UI的基础。无论有没有前端的开发经验,相信大家都听过著名的CSS盒子模型。

盒子模型基于position、浮动属性等进行布局,但是对于一些比较特殊但是常用的布局就比较困难,如垂直居中。

于是, 在2009年, W3C提出了一种新的方案一-Flexbox布局。Flexbox(FlexibleBox 的缩写,又称弹性盒子布局〉布局旨在提供一个更加有效的方式制定 、调整和分布一个容 器里的项目布局,即使他们的大小是未知或者动态的。 Flexbox 布局的主要思想是让容器 有能力让其子项目 能够改变其宽度、 高度(甚至顺序),以最佳方式填充可用空间 (主要 是为 了适应所有类型 的显示设备和屏幕大小) 。

React Native实现了Flexbox的大部分的功能,这使得React Native的UI布局更加简单,并且更容易适配iOS、Android的屏幕。

2.属性介绍

Flexbox布局简单概括包括两种:

  • 指定子空间排列规则的属性,如flexDirection、flexWrap、justifyContent和alignItems等
  • 指定自身的显示属性,如algnSelf和flex等

2.1 flexDirection设置排列方式

flexDirection可指定子控件的排列方向,取值包括:column(默认值)、row和row-reverse。

示例:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray'
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green'
  }
})

const MyApp = () => {
  return (
    <View style={flexStyles.container}>
      <View style={flexStyles.view1}/>
      <View style={flexStyles.view2}/>
    </View>
  );
}

export default MyApp;

效果如下:

默认采用的是column的方式排列,如果更换为row时,代码如下:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'row'\改为row
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green'
  }
})
...

效果如下:

最后时row-revere,效果时前后反序排列,这个就不写了,大家自己试一下吧。

2.2 flexWrap设置换行

flexWrap表示当子View超出父View时是否进行换行,取值包括:nowrap(默认值)、wrap和wrap-reverse,示例:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'row',
  },view1: {
    width: 300,
    height: 300,
    backgroundColor: 'red'
  },
  view2: {
    width: 300,
    height: 300,
    backgroundColor: 'green'
  }
})

const MyApp = () => {
  return (
    <View style={flexStyles.container}>
      <View style={flexStyles.view1}/>
      <View style={flexStyles.view2}/>
    </View>
  );
}

export default MyApp;

效果如下:

默认为超出时依然按原有布局展示,view2只有部分可正常展示,当flexWrap设置为wrap时,代码如下:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'row',
    flexWrap: 'wrap'\修改为wrap
  },view1: {
    width: 300,
    height: 300,
    backgroundColor: 'red'
  },
  view2: {
    width: 300,
    height: 300,
    backgroundColor: 'green'
  }
})
...

效果如下:

当子View超出父View范围后,会自动换行显示

2.3 justifyContent设置横向排列位置

justifyContent 指定子View横向排列在其父View的哪个位置,取值有 flex-start、 flex-end、 center、 space-between 以及 space-around。 示例:

const flexStyles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    backgroundColor: 'gray',
    justifyContent: 'flex-start'
  },container2: {
    flexDirection: 'row',
    backgroundColor: 'gray',
    justifyContent: 'flex-end'
  },container3: {
    flexDirection: 'row',
    backgroundColor: 'gray',
    justifyContent: 'center'
  },container4: {
    flexDirection: 'row',
    backgroundColor: 'gray',
    justifyContent: 'space-between'
  },container5: {
    flexDirection: 'row',
    backgroundColor: 'gray',
    justifyContent: 'space-around'
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green'
  }
})

const MyApp = () => {
  return (
    <View>
      <View style={flexStyles.container}>
        <View style={flexStyles.view1}/>
        <View style={flexStyles.view2}/>
      </View>
      <Text>flex-start</Text>
      <View style={flexStyles.container2}>
        <View style={flexStyles.view1}/>
        <View style={flexStyles.view2}/>
      </View>
      <Text>flex-end</Text>
      <View style={flexStyles.container3}>
        <View style={flexStyles.view1}/>
        <View style={flexStyles.view2}/>
      </View>
      <Text>center</Text>
      <View style={flexStyles.container4}>
        <View style={flexStyles.view1}/>
        <View style={flexStyles.view2}/>
      </View>
      <Text>space-between</Text>
      <View style={flexStyles.container5}>
        <View style={flexStyles.view1}/>
        <View style={flexStyles.view2}/>
      </View>
      <Text>space-around</Text>
    </View>
    
  );
}

export default MyApp;

效果图:

2.4 alignItems设置纵向排列位置

alignItems与justifyContent相似,只是alignItems设置的是子View纵向排列的位置。取值包括:flex-start、flex-end、center、baseLine和stretch,示例:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'row',
    alignItems: 'center'
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green'
  }
})

const MyApp = () => {
  return (
    <View style={flexStyles.container}>
      <View style={flexStyles.view1}/>
      <View style={flexStyles.view2}/>
    </View>
  );
}

export default MyApp;

效果如下:

基于alignItems和justifyContent可以很轻易的实现屏幕居中:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center'
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green'
  }
})

效果:

2.5 alignSelf设置特定View的排列

alignSelf可以设置当前View自身的排列情况,取值包括:auto、flex-start、flex-end、center和stretch。以居中为例:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'column'
  },view1: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
  view2: {
    width: 100,
    height: 100,
    backgroundColor: 'green',
    alignSelf: 'center'
  }
})

const MyApp = () => {
  return (
    <View style={flexStyles.container}>
      <View style={flexStyles.view1}/>
      <View style={flexStyles.view2}/>
    </View>
  );
}

export default MyApp;

效果如下:

2.6 flex设置View所占空间

flex可以让组件动态计算和设置自身所占用的空间大小,如果想让view1和view2填满父View,并且view1和view2大小相同,如下:

const flexStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'gray',
    flexDirection: 'column'
  },view1: {
    flex: 1,
    backgroundColor: 'red'
  },
  view2: {
    flex: 1,
    backgroundColor: 'green'
  }
})

const MyApp = () => {
  return (
    <View style={flexStyles.container}>
      <View style={flexStyles.view1}/>
      <View style={flexStyles.view2}/>
    </View>
  );
}

export default MyApp;

效果如下:

3.总结

本章主要介绍了React Native中的Flexbox模型,包括:flexDirection、flexWrap、justifyContent、alignItems、alignSelf和flex等属性,相信基于本章的内容,我们可以熟悉使用rn来实现简单的页面布局。