React Native中的Flexbox属性指南

187 阅读9分钟

如果你有网页设计和/或开发背景,你可能对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伸展柔性开始
柔性收缩10

主要的Flexbox属性

有几个你会经常使用的Flexbox属性值得你记住。下面是对它们的介绍,以及它们的作用。

  • flex - 定义了该视图在屏幕上的填充程度。可用的值是大于或等于0的整数。
  • flexDirection - 决定孩子们在哪个方向--垂直或水平方向--进行布局。可用的值包括column,row,column-reverse, 和row-reverse
  • justifyContent - 决定一个项目应该如何沿着主轴线渲染(由flexDirection 属性决定)。可用的值包括:flex-start,flex-end,center,space-between,space-around, 和space-evenly
  • alignItems - 这决定了一个项目应该如何沿次要轴线呈现(由flexDirection 属性决定)。可用的值是flex-start,flex-end,center, 和baseline
  • alignSelf - 决定一个子项应该如何对齐自己,并覆盖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 Property Filling Entire Mobile Screen Green

在这种情况下,视图将占满整个屏幕。为什么呢?因为它的属性是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 Property Filling Top Quarter Of Mobile Screen In Green

另外,我们可以看到,尽管有相同的flex ,但绿色区域现在只占了屏幕的四分之一。这是因为屏幕现在被分成了四个区块(1+3),所以flex 属性是它应该占据屏幕的一部分。

在Flexbox中使用flexDirection

FlexDirection 决定了儿童应该呈现的方向。你可以用以下值进行编码:columnrowcolumn-reverserow-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,
  },
});

Flex Direction Property Creating A Column Of Three Green Squares On The Center Of Mobile Screen
现在,让我们使用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,
  },
});

Flex Direction Property Creating Row Of Three Green Squares On Mobile Screen

请注意,使用*-reverse 只是颠倒了它们的渲染顺序。

在Flexbox中使用justifyContent 属性

justifyContent 决定沿着主轴的内容,该内容受到flexDirection 的影响。如果flexDirectioncolumn ,那么它就是垂直的。如果它被归类为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,
  },
});

Justify Content Property Creating Row Of Three Green Squares On The Left Side Of Mobile Screen

接下来,我们使用了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,
  },
});

Space Around Property Increased Space In Between Three Green Squares On The Left Side Of Mobile Screen

这些属性中的每一个都允许你做出独特的布局。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,
  },
});

Align Items Property Creating Horizontal Group Of Three Squares On The Center Of Mobile Screen

同样,当把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,
  },
});

Flex End Property Creating Horizontal Group Of Three Squares On The Right Side Of Mobile Screen

使用alignSelf

alignSelf 决定一个子元素应该如何对齐,并且它覆盖了alignItemsalignSelf 的可用值是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,
  },
});

下面是它的样子。

Align Self Property Overriding Align Items To Create A Square In The Center, And On The Left And Right Sides Of Mobile Screen

建立一个Flexbox网格

现在我们知道了Flexbox中每个属性的作用,让我们用Flexbox创建一个网格。我们的最终目标是你在下一张图片中看到的。请随意使用启动代码,在跟读之前自己尝试一下。

Three By Three Grid Containing Letters "A" Through "I" On Mobile Screen

// 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>
  );
}

Letters "A" Through "I" Displayed Horizontally On The Center Of Mobile Screen

我们在这里添加了一些样式属性,即styles.rowstyles.square

我们知道这一行应该把它的项目渲染成一排,所以我们来设置它的flexDirection: 'row'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#7CA1B4",
    alignItems: "center",
    justifyContent: "center",
  },
  row: {
    flexDirection: "row",
  },
});

Flex Direction Row Property Stacking Letters A,B,C, On Top Of Letters D,E,F, On Top Of Letters G,H,I In Center Of Mobile Screen

接下来,我们将用适当的边框、高度和宽度以及文本颜色来创建广场本身。然后,我们可以在该正方形上使用justifyContentalignItems ,使文本在其内垂直和水平居中。看看吧。

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",
  },
});

Three By Three Grid Containing Letters "A" Through "I" on Mobile Screen

这就给我们留下了最后的代码。

// 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",
  },
});

Card Image Of River And Mountains With Text On The Header And Footer Displayed In The Center Of Mobile Screen

现在让我们来处理标题。我们希望文本以单行形式呈现,并 "粘 "在每个边缘。我们可以通过定义flexDirectionjustifyContent 来达到这个目的。我们还将设置一些垂直和水平的填充。

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,
  },
});

Card With Increased Header Space Stating "React Native School" And "Follow" On The Same Line

最后是页脚。我们在这里所要做的就是设置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",
  },
});

Card With Increased Footer Space Stating "React Native School This has been a tutorial on how to build a layout with Flexbox. I hope you enjoyed it!"

这就是关于在React Native中使用Flexbox来构建布局的介绍Flexbox是一个动态的、强大的工具,完全适合移动环境。

要了解更多关于一些更晦涩的属性,请查看React Native的文档

The postA guide to Flexbox properties in React Nativeappeared first onLogRocket Blog.