如果你有网页设计和/或开发背景,你可能对Flexbox很熟悉。它是一个可选择的CSS工具,使你能够建立基于列和行的布局。
在React Native中,这是构建布局的默认方式。它对移动开发非常有效,因为它允许我们建立适合多种屏幕尺寸的布局,这要感谢响应式设计。
Flexbox。为React Native开发与网络开发
Flexbox在React Native中是默认的,但我们不必选择加入它,这意味着你不需要在样式中设置display: flex 。
const styles = StyleSheet.create({
card: {
display: 'flex' // this is unnecessary
}
});
还有一些不同的默认值,使Flexbox更有利于移动开发。
| 属性 | 网络默认 | React Native默认 |
|---|---|---|
| flexDirection | 行 | 列 |
| alignContent | 伸展 | 柔性开始 |
| 柔性收缩 | 1 | 0 |
主要的Flexbox属性
有几个你会经常使用的Flexbox属性值得你记住。下面是对它们的介绍,以及它们的作用。
flex- 定义了该视图在屏幕上的填充程度。可用的值是大于或等于0的整数。flexDirection- 决定孩子们在哪个方向--垂直或水平方向--进行布局。可用的值包括column,row,column-reverse, 和row-reversejustifyContent- 决定一个项目应该如何沿着主轴线渲染(由flexDirection属性决定)。可用的值包括:flex-start,flex-end,center,space-between,space-around, 和space-evenlyalignItems- 这决定了一个项目应该如何沿次要轴线呈现(由flexDirection属性决定)。可用的值是flex-start,flex-end,center, 和baselinealignSelf- 决定一个子项应该如何对齐自己,并覆盖alignItems。可用的值是:flex-start,flex-end,center, 和baseline
你可以在官方文档中了解更多关于Flexbox的布局。现在,让我们深入了解每个属性的作用以及如何使用它。
在Flexbox和React Native中使用flex 属性
flex 属性决定了视图如何填满屏幕。为了说明这一点,让我们看一下两个代码非常相似的例子。
注意,可用的值包括大于或等于0的整数。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={{ backgroundColor: "#7cb48f", flex: 1 }} />
</>
);
}
这就是结果。
在这种情况下,视图将占满整个屏幕。为什么呢?因为它的属性是flex: 1 ,而且因为空间被分成了一组(1/1),它将占据100%的屏幕。
让我们看看第二个例子,使用下面的代码。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={{ backgroundColor: "#7cb48f", flex: 1 }} />
<View style={{ backgroundColor: "#7CA1B4", flex: 3 }} />
</>
);
}
另外,我们可以看到,尽管有相同的flex ,但绿色区域现在只占了屏幕的四分之一。这是因为屏幕现在被分成了四个区块(1+3),所以flex 属性是它应该占据屏幕的一部分。
在Flexbox中使用flexDirection
FlexDirection 决定了儿童应该呈现的方向。你可以用以下值进行编码:column 、row 、column-reverse 、row-reverse ,但默认是column 。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
alignItems: "center", // ignore this - we'll come back to it
justifyContent: "center", // ignore this - we'll come back to it
flexDirection: "column"
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
现在,让我们使用flexDirection ofrow ,将方向从一列改为一行。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
alignItems: "center", // ignore this - we'll come back to it
justifyContent: "center", // ignore this - we'll come back to it
flexDirection: "row",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
请注意,使用*-reverse 只是颠倒了它们的渲染顺序。
在Flexbox中使用justifyContent 属性
justifyContent 决定沿着主轴的内容,该内容受到flexDirection 的影响。如果flexDirection 是column ,那么它就是垂直的。如果它被归类为row ,它就是水平的。
作为提醒,以下是可用的值:flex-start,flex-end,center,space-between,space-around, 和space-evenly 。
下面我们将justifyContent 设置为center 。因为主轴是一个列,这意味着我们将把内容垂直居中。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
justifyContent: "center",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
接下来,我们使用了space-around 属性。这将导致布局沿着主(垂直)轴均匀地分割元素。这意味着,从屏幕的顶部和底部到每个元素之间的距离将是相等的。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
justifyContent: "space-around",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
这些属性中的每一个都允许你做出独特的布局。flex-start 将使项目在屏幕的顶部对齐,flex-end 将使项目在底部对齐,space-between 将使项目之间的距离最大化(即,盒子1将在屏幕的最顶部,盒子3在底部,而盒子2在中间)。
使用alignItems
alignItems 决定一个项目应该如何沿次轴渲染,次轴由flexDirection 属性决定。这是对justifyContent 的逆运算。因此,如果justifyContent 是处理垂直对齐,那么alignItems 是处理水平对齐。
可用值:flex-start,flex-end,center, 和baseline 。
下面,我们看到当使用默认的flexDirection (column)时,alignItems 可以被用来将内容水平居中。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
justifyContent: "center",
alignItems: "center",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
同样,当把alignItems 设置为flex-end ,我们看到元素移动到柔性区域的末端,即最右边。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={styles.square} />
<View style={styles.square} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
justifyContent: "center",
alignItems: "flex-end",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
使用alignSelf
alignSelf 决定一个子元素应该如何对齐,并且它覆盖了alignItems 。alignSelf 的可用值是flex-start,flex-end,center,baseline 。
下面,我们设置了一个默认的alignItems 属性,然后用alignSelf 覆盖它。
import React from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
return (
<>
<View style={styles.container}>
<View style={styles.square} />
<View style={[styles.square, { alignSelf: "flex-end" }]} />
<View style={[styles.square, { alignSelf: "flex-start" }]} />
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#7CA1B4",
flex: 1,
justifyContent: "center",
alignItems: "center",
},
square: {
backgroundColor: "#7cb48f",
width: 100,
height: 100,
margin: 4,
},
});
下面是它的样子。
建立一个Flexbox网格
现在我们知道了Flexbox中每个属性的作用,让我们用Flexbox创建一个网格。我们的最终目标是你在下一张图片中看到的。请随意使用启动代码,在跟读之前自己尝试一下。
// starter.js
import React from "react";
import { StyleSheet, View, Text } from "react-native";
export default function App() {
return <View style={styles.container}></View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
});
看一下示例图片,我们可以把它分解成三行,每行都有自己的三列。每个方块都应该在垂直和水平方向上呈现其文本。
我将创建一个Square 组件,以节省一些重复的工作。
import React from "react";
import { StyleSheet, View, Text } from "react-native";
const Square = ({ text }) => (
<View style={styles.square}>
<Text style={styles.text}>{text}</Text>
</View>
);
export default function App() {
return (
<View style={styles.container}>
<View style={styles.row}>
<Square text="A" />
<Square text="B" />
<Square text="C" />
</View>
<View style={styles.row}>
<Square text="D" />
<Square text="E" />
<Square text="F" />
</View>
<View style={styles.row}>
<Square text="G" />
<Square text="H" />
<Square text="I" />
</View>
</View>
);
}
我们在这里添加了一些样式属性,即styles.row 和styles.square 。
我们知道这一行应该把它的项目渲染成一排,所以我们来设置它的flexDirection: 'row' 。
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
row: {
flexDirection: "row",
},
});
接下来,我们将用适当的边框、高度和宽度以及文本颜色来创建广场本身。然后,我们可以在该正方形上使用justifyContent 和alignItems ,使文本在其内垂直和水平居中。看看吧。
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
row: {
flexDirection: "row",
},
square: {
borderColor: "#fff",
borderWidth: 1,
width: 100,
height: 100,
justifyContent: "center",
alignItems: "center",
},
text: {
color: "#fff",
fontSize: 18,
fontWeight: "bold",
},
});
这就给我们留下了最后的代码。
// finished.js
import React from "react";
import { StyleSheet, View, Text } from "react-native";
const Square = ({ text }) => (
<View style={styles.square}>
<Text style={styles.text}>{text}</Text>
</View>
);
export default function App() {
return (
<View style={styles.container}>
<View style={styles.row}>
<Square text="A" />
<Square text="B" />
<Square text="C" />
</View>
<View style={styles.row}>
<Square text="D" />
<Square text="E" />
<Square text="F" />
</View>
<View style={styles.row}>
<Square text="G" />
<Square text="H" />
<Square text="I" />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
row: {
flexDirection: "row",
},
square: {
borderColor: "#fff",
borderWidth: 1,
width: 100,
height: 100,
justifyContent: "center",
alignItems: "center",
},
text: {
color: "#fff",
fontSize: 18,
fontWeight: "bold",
},
});
如果你对一个使用FlatList的稍微复杂的例子感兴趣,这使得它可以滚动,我已经在React Native School上介绍了这个主题。
设计一个Flexbox卡片
接下来,让我们尝试使用Flexbox构建一个卡片布局。还是那句话,你可以拿着启动代码,先自己试试。
// start.js
import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<View>
<View>
<Text style={styles.nameText}>React Native School</Text>
<Text style={styles.followText}>Follow</Text>
</View>
<Image
style={styles.image}
resizeMode="cover"
source={{
uri:
"<https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?cs=srgb&dl=pexels-michael-block-3225517.jpg&fm=jpg>",
}}
/>
<View>
<Text>
<Text style={styles.nameText}>{`React Native School `}</Text>
This has been a tutorial on how to build a layout with Flexbox. I
hope you enjoyed it!
</Text>
</View>
</View>
</View>
);
}
const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
},
image: {
height: screen.width * 0.8,
},
nameText: {
fontWeight: "bold",
color: "#20232a",
},
followText: {
fontWeight: "bold",
color: "#0095f6",
},
});
让我们先把卡片和容器放在一起。首先,我们在水平和垂直方向上对准卡片。我们还为卡片设置了一个宽度,即屏幕宽度的80%,像这样。
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
{/* ... */}
</View>
</View>
);
}
const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
card: {
backgroundColor: "#fff",
width: screen.width * 0.8,
},
image: {
height: screen.width * 0.8,
},
nameText: {
fontWeight: "bold",
color: "#20232a",
},
followText: {
fontWeight: "bold",
color: "#0095f6",
},
});
现在让我们来处理标题。我们希望文本以单行形式呈现,并 "粘 "在每个边缘。我们可以通过定义flexDirection 和justifyContent 来达到这个目的。我们还将设置一些垂直和水平的填充。
import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
<View style={styles.header}>
<Text style={styles.nameText}>React Native School</Text>
<Text style={styles.followText}>Follow</Text>
</View>
{/* ... */}
</View>
</View>
);
}
const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
// ...
header: {
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 15,
paddingVertical: 10,
},
});
最后是页脚。我们在这里所要做的就是设置padding!这是为什么呢?因为我们已经嵌套了我们的Text 组件并对名称部分应用了样式,所以我们不需要担心这里的布局。工作更聪明,而不是更难!这就是最终的结果。
// finished.js
import React from "react";
import { StyleSheet, View, Text, Image, Dimensions } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
<View style={styles.header}>
<Text style={styles.nameText}>React Native School</Text>
<Text style={styles.followText}>Follow</Text>
</View>
<Image
style={styles.image}
resizeMode="cover"
source={{
uri:
"<https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?cs=srgb&dl=pexels-michael-block-3225517.jpg&fm=jpg>",
}}
/>
<View style={styles.footer}>
<Text>
<Text style={styles.nameText}>{`React Native School `}</Text>
This has been a tutorial on how to build a layout with Flexbox. I
hope you enjoyed it!
</Text>
</View>
</View>
</View>
);
}
const screen = Dimensions.get("screen");
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#7CA1B4",
alignItems: "center",
justifyContent: "center",
},
card: {
backgroundColor: "#fff",
width: screen.width * 0.8,
},
header: {
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 15,
paddingVertical: 10,
},
image: {
height: screen.width * 0.8,
},
footer: {
paddingHorizontal: 15,
paddingVertical: 10,
},
nameText: {
fontWeight: "bold",
color: "#20232a",
},
followText: {
fontWeight: "bold",
color: "#0095f6",
},
});
这就是关于在React Native中使用Flexbox来构建布局的介绍Flexbox是一个动态的、强大的工具,完全适合移动环境。
要了解更多关于一些更晦涩的属性,请查看React Native的文档。
The postA guide to Flexbox properties in React Nativeappeared first onLogRocket Blog.