react-native中,使用 Flexbox 布局使用示例

84 阅读1分钟

下面的示例展示了不同的布局样式,对布局的影响

image.png

import React, { useState } from "react";
import {
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";

const FlexDirectionBasics = () => {
  const [flexDirection, setflexDirection] = useState("row");
  const [direction, setDirection] = useState("ltr");
  const [justifyContent, setJustifyContent] = useState("flex-start");
  const [alignItems, setAlignItems] = useState("stretch");
  const [alignContent, setAlignContent] = useState("flex-start");
  const [flexWrap, setFlexWrap] = useState("wrap");

  const styleCollection = [
    {
      // 子组件的主轴方向
      label: "flexDirection",
      values: ["column", "row", "row-reverse", "column-reverse"],
      stateValue: flexDirection,
      setStateValue: setflexDirection,
    },
    {
      // 子组件在主轴上的排列方向,从左到右,还是从右到左
      label: "direction",
      values: ["ltr", "rtl"],
      stateValue: direction,
      setStateValue: setDirection,
    },
    {
      // 子组件在主轴上的排列方式
      label: "justifyContent",
      values: [
        "flex-start",
        "flex-end",
        "center",
        "space-between",
        "space-around",
        "space-evenly",
      ],
      stateValue: justifyContent,
      setStateValue: setJustifyContent,
    },
    {
      // flexWrap 用于设置容器的换行方式,控制子元素超出容器时(是否换行)
      label: "flexWrap",
      values: [
        "wrap", "nowrap",
      ],
      stateValue: flexWrap,
      setStateValue: setFlexWrap,
    },
    {
      // alignItems 子元素在次轴上的排列方式
      label: "alignItems",
      tips: "flexWrap 设置为 nowrap 时生效",
      values: ["stretch", "flex-start", "flex-end", "center", "baseline"],
      stateValue: alignItems,
      setStateValue: setAlignItems,
    },
    {
      // alignContent 定义了如何沿次轴方向分布行。只有在使用 flexWrap 将项目换行到多个行时才会生效
      label: "alignContent",
      tips: "flexWrap 设置为 wrap 时生效",
      values: [
        "flex-start",
        "flex-end",
        "stretch",
        "center",
        "space-between",
        "space-around",
      ],
      stateValue: alignContent,
      setStateValue: setAlignContent,
    },
  ];

  return (
    <PreviewLayout styleCollection={styleCollection}>
      <View style={[styles.box, { backgroundColor: "orangered" }]} />
      <View style={[styles.box, { backgroundColor: "orange" }]} />
      {/* <View style={[styles.box, { backgroundColor: "mediumseagreen" }]} />
      <View style={[styles.box, { backgroundColor: "deepskyblue" }]} />
      <View style={[styles.box, { backgroundColor: "mediumturquoise" }]} />
      <View style={[styles.box, { backgroundColor: "mediumslateblue" }]} />
      <View style={[styles.box, { backgroundColor: "purple" }]} /> */}
    </PreviewLayout>
  );
};

const PreviewLayout = ({ children, styleCollection }) => (
  <>
    <ScrollView>
      <View style={{ padding: 10, flex: 1 }}>
        {styleCollection.map((item) => (
          <StyleSelect key={item.label} {...item}></StyleSelect>
        ))}
      </View>
      <View style={{ minHeight: 300 }}>
        <View style={{ padding: 10, flex: 1 }}>
          <View
            style={[
              styles.container,
              ...styleCollection.map((item) => {
                return {
                  [item.label]: item.stateValue,
                };
              }),
            ]}
          >
            {children}
          </View>
        </View>
      </View>
    </ScrollView>
  </>
);
function StyleSelect({ label, values, stateValue, setStateValue,tips = null }) {
  return (
    <>
      <Text style={styles.label}>{label}</Text>
      {tips && <Text >{tips}</Text>}
      <View style={styles.row}>
        {values.map((value) => (
          <TouchableOpacity
            key={value}
            onPress={() => setStateValue(value)}
            style={[styles.button, stateValue === value && styles.selected]}
          >
            <Text
              style={[
                styles.buttonLabel,
                stateValue === value && styles.selectedLabel,
              ]}
            >
              {value}
            </Text>
          </TouchableOpacity>
        ))}
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexWrap: "wrap",
    marginTop: 8,
    backgroundColor: "aliceblue",
    maxHeight: 400,
  },
  box: {
    width: 50,
    height: 50,
  },
  row: {
    flexDirection: "row",
    flexWrap: "wrap",
  },
  button: {
    paddingHorizontal: 8,
    paddingVertical: 6,
    borderRadius: 4,
    backgroundColor: "oldlace",
    alignSelf: "flex-start",
    marginHorizontal: "1%",
    marginBottom: 6,
    minWidth: "48%",
    textAlign: "center",
  },
  selected: {
    backgroundColor: "coral",
    borderWidth: 0,
  },
  buttonLabel: {
    fontSize: 12,
    fontWeight: "500",
    color: "coral",
  },
  selectedLabel: {
    color: "white",
  },
  label: {
    textAlign: "center",
    marginBottom: 10,
    fontSize: 24,
  },
});

export default FlexDirectionBasics;

参考: 使用 Flexbox 布局