本文总结:
我们学到了 React Native 的 Flexbox 布局,它让写样式变得更方便啦!😊 Flexbox 就像一个有弹性的盒子,有主轴和交叉轴(行或列)。
在 RN 里写样式要用 StyleSheet.create 对象,属性名是驼峰命名。
文章还介绍了如何用 Platform.select 给不同平台写样式,以及使用 styled-components 这个库的简单例子(虽然我们主要还是用 StyleSheet)。
文章还通过三栏布局和横向布局的例子,展示了 flexDirection, alignItems, justifyContent 和 alignSelf 这些属性的用法。
特别喜欢 alignSelf: 'stretch' 能让元素填充空间的技巧!👍
最后,通过抽象出 Row 和 Col 组件,我看到了如何用 Flexbox 实现更复杂的嵌套布局。感觉 Flexbox 真的让布局变得灵活多了!🚀
1、关于 Flexbox
在将flexbox引入css前,构建布局的各种css属性都比较粗糙,而且很容易出错。而flexbox通过抽象了很多属性来解决问题。字如其名flexbox的意思就是一个具有弹性的盒子模型。我们画个图:假设你有一个容器和它的子元素,它看起来可以是这样的。
Flexbox
容器有二个轴,即列(向上/向下)或行(左/右)。
2、实操
我们直接上代码吧,这是一个js模块,而不是css模块。如果我们要声明rn的样式,我们需要去定义一个对象然后调用StyleSheet.create()最后抛出它在你的模块中。但是我们需要注意的是rn只支持驼峰命名。
 import { Platform, StyleSheet, StatusBar } from 'react-native'export default StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: 'ghostwhite',    ...Platform.select({      ios: { paddingTop: 20 },      android: { paddingTop: StatusBar.currentHeight },    }),  },  box: {    width: 100,    height: 100,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: 'lightgray',  },  boxText: {    color: 'darkslategray',    fontWeight: 'bold',  },})
       复制代码
 然后我们看到刚才我写了这样一段代码,这里其实就是根据你的移动端去选择样式。
 ...Platform.select({  ios: { paddingTop: 20 },  android: { paddingTop: StatusBar.currentHeight },}),
       复制代码
 ok,我们看一下在rn组件中如何使用
 import { Text, View } from 'react-native'import styles from './styles'export default function App() {  return (      <View style={styles.container}>      <View style={styles.box}>        <Text style={styles.boxText}>I'm in a box</Text>      </View>    </View>  )}
       复制代码
 这些样式将通过样式属性分配给每个组件。我们来看看它的表现。
3、Styled-components 样式组件库使用
Styled-components
是一个css-in-js的库为我们的组件去提供样式,如我们去直接看看怎么使用吧。当然只是介绍一下,我们还是使用styleSheet。
首先下载依赖
 
yarn add styled-components
       复制代码
 然后我们写点代码
 import styled from "styled-components/native";const Box = styled.View'    width: 100px;    height: 100px;    justify-content: center;    align-items: center;    background-color: lightgray;';const BoxText = styled.Text'    color: darkslategray;    font-weight: bold;';
       复制代码
 使用
 const App = () => {return (    <Box>        <BoxText>I'm in a box</BoxText>    </Box>);
};
       复制代码
 4、基础 Flexbox
接下来主要讲一下rn中的几种常见布局和flexbox的实战
4.1、三栏布局
普通的从上到下的三栏布局。
你可以把view理解成div,text理解成p。
 import { Text, View } from 'react-native'import styles from './styles'export default function App() {  return (      <View style={styles.container}>      <View style={styles.box}>        <Text style={styles.boxText}>#1</Text>      </View>      <View style={styles.box}>        <Text style={styles.boxText}>#2</Text>      </View>      <View style={styles.box}>        <Text style={styles.boxText}>#3</Text>      </View>    </View>  )}
       复制代码
 flexDirection
属性是决定了主轴的方向,上到下或者左到右,而alignItem和justifyContent属性决定了元素的排列和间隔。
 
import { Platform, StyleSheet, StatusBar } from 'react-native'export default StyleSheet.create({  container: {    flex: 1,    flexDirection: 'column',    alignItems: 'center',    justifyContent: 'space-around',    backgroundColor: 'ghostwhite',    ...Platform.select({      ios: { paddingTop: 20 },      android: { paddingTop: StatusBar.currentHeight },    }),  },  box: {    width: 300,    height: 100,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: 'lightgray',    borderWidth: 1,    borderStyle: 'dashed',    borderColor: 'darkslategray',  },  boxText: {    color: 'darkslategray',    fontWeight: 'bold',  },})
       复制代码
 而如果我们想让它左右两边填满那?就像这样
我们可以加入alignSelf这个属性,这个属性的意思是根据主轴flexDirection的方向,改变宽度或者高度(column 改变的就是宽度,row 改变的就是高度)去填充空白,动态计算高度或宽度。像这样就是会填满你屏幕的宽度。
   box: {    height: 100,    justifyContent: 'center',    //     alignSelf: 'stretch',    alignItems: 'center',    backgroundColor: 'lightgray',    borderWidth: 1,    borderStyle: 'dashed',    borderColor: 'darkslategray',  },
       复制代码
  当我们把手机横过去
我们稍微优化一下,正好也写一下横向的布局,上面的样式太`抽象`了写得。
 import { Text, View, StatusBar } from 'react-native'import styles from './styles'import Box from './Box'export default function App() { return (    <View style={styles.container}>     <Box>#1</Box>     <Box>#2</Box>   </View> )}
       复制代码
 
 import { PropTypes } from 'prop-types'import { View, Text } from 'react-native'import styles from './styles'export default function Box({ children }) { return (   <View style={styles.box}>     <Text style={styles.boxText}>{children}</Text>   </View> )}Box.propTypes = { children: PropTypes.node.isRequired,}
       复制代码
 这个就是会拉伸至整个屏幕高度的横向布局
 import { Platform, StyleSheet, StatusBar } from 'react-native'export default StyleSheet.create({  container: {    flex: 1,    flexDirection: 'row',    backgroundColor: 'ghostwhite',    alignItems: 'center',    justifyContent: 'space-around',    ...Platform.select({      ios: { paddingTop: 20 },      android: { paddingTop: StatusBar.currentHeight },    }),  },  box: {    width: 100,    justifyContent: 'center',    alignSelf: 'stretch',    alignItems: 'center',    backgroundColor: 'lightgray',    borderWidth: 1,    borderStyle: 'dashed',    borderColor: 'darkslategray',  },  boxText: {    color: 'darkslategray',    fontWeight: 'bold',  },})
       复制代码
 我们来看看它的表现
当我们把手机横过去
5、稍微复杂一点的 flexBox
假设我们要实现这样一个效果,我们该如何实现?
在我们的意识中,整个布局有行、列。那我们同样也可以抽象出col、row组件分别代表行列。我们直接上代码吧。
可以看到我们分别确定了col、row的方向和排列。
 import { Platform, StyleSheet, StatusBar } from 'react-native'
export default StyleSheet.create({  container: {    flex: 1,    flexDirection: 'column',    backgroundColor: 'ghostwhite',    alignItems: 'center',    justifyContent: 'space-around',    ...Platform.select({      ios: { paddingTop: 40 },      android: { paddingTop: StatusBar.currentHeight },    }),  },
  box: {    height: 100,    width: 100,    justifyContent: 'center',    alignItems: 'center',    borderWidth: 1,    borderStyle: 'dashed',    borderColor: 'darkslategray',    backgroundColor: 'lightgray',  },
  boxText: {    color: 'darkslategray',    fontWeight: 'bold',  },
  row: {    flex: 1,    flexDirection: 'row',    justifyContent: 'space-around',    alignSelf: 'stretch',  },
  column: {    flex: 1,    flexDirection: 'column',    alignItems: 'center',    justifyContent: 'space-around',    alignSelf: 'stretch',  },})
       复制代码
 组件部分
app
 import { View, StatusBar } from 'react-native'import styles from './styles'import Row from './Row'import Col from './Col'import Box from './Box'export default function App() {  return (  <View style={styles.container}>      <StatusBar hidden={false} />      <Row>        <Col>          <Box>#1</Box>          <Box>#2</Box>        </Col>        <Col>          <Box>#3</Box>          <Box>#4</Box>        </Col>      </Row>      <Row>        <Col>          <Box>#5</Box>          <Box>#6</Box>        </Col>        <Col>          <Box>#7</Box>          <Box>#8</Box>        </Col>      </Row>      <Row>        <Col>          <Box>#9</Box>          <Box>#10</Box>        </Col>        <Col>          <Box>#11</Box>          <Box>#12</Box>        </Col>      </Row>    </View>  )}
       复制代码
 col
 import PropTypes from 'prop-types'import { View } from 'react-native'import styles from './styles'export default function Column({ children }) {  return <View style={styles.column}>{children}</View>}
Column.propTypes = {  children: PropTypes.node.isRequired,}
       复制代码
 row
 import PropTypes from 'prop-types'import { View } from 'react-native'import styles from './styles'export default function Row({ children }) {  return <View style={styles.row}>{children}</View>}
Row.propTypes = {  children: PropTypes.node.isRequired,}
       复制代码
 
 
import React from 'react'import PropTypes from 'prop-types'import { View, Text } from 'react-native'import styles from './styles'export default function Box({ children }) {  return (    <View style={styles.box}>      <Text style={styles.boxText}>{children}</Text>    </View>  )}
Box.propTypes = {  children: PropTypes.node.isRequired,}
       复制代码
 6、总结
关于我
评论