Skip to content

Flex 布局(移动端核心布局)

React Native 核心基础

Flex 布局(弹性布局)是 React Native 中最常用的布局方式,它提供了一种灵活的方式来排列和对齐组件。

1. 基本概念

Flex 容器

要使用 Flex 布局,首先需要将容器的 flexDirection 属性设置为 rowcolumnrow-reversecolumn-reverse

Flex 项目

容器中的子元素就是 Flex 项目,它们会按照 Flex 布局的规则排列。

主轴和交叉轴

  • 主轴:Flex 项目排列的方向
  • 交叉轴:与主轴垂直的方向

2. 常用属性

容器属性

属性描述可选值
flexDirection主轴方向rowcolumnrow-reversecolumn-reverse
justifyContent主轴对齐方式flex-startflex-endcenterspace-betweenspace-aroundspace-evenly
alignItems交叉轴对齐方式flex-startflex-endcenterstretchbaseline
flexWrap是否换行nowrapwrapwrap-reverse
alignContent多轴线对齐方式flex-startflex-endcenterspace-betweenspace-aroundstretch

项目属性

属性描述示例
flex弹性比例flex: 1
alignSelf单个项目的交叉轴对齐方式alignSelf: 'center'
flexGrow项目的放大比例flexGrow: 1
flexShrink项目的缩小比例flexShrink: 1
flexBasis项目的初始大小flexBasis: '50%'
order项目的排列顺序order: 2

3. 基本布局示例

水平布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function HorizontalLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={[styles.box, styles.box1]}>
        <Text style={styles.text}>Box 1</Text>
      </View>
      <View style={[styles.box, styles.box2]}>
        <Text style={styles.text}>Box 2</Text>
      </View>
      <View style={[styles.box, styles.box3]}>
        <Text style={styles.text}>Box 3</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row', // 水平布局
    justifyContent: 'space-around',
    alignItems: 'center',
    padding: 20,
  },
  box: {
    width: 80,
    height: 80,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
  },
  box1: {
    backgroundColor: '#4CAF50',
  },
  box2: {
    backgroundColor: '#2196F3',
  },
  box3: {
    backgroundColor: '#FFC107',
  },
  text: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

垂直布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function VerticalLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={[styles.box, styles.box1]}>
        <Text style={styles.text}>Box 1</Text>
      </View>
      <View style={[styles.box, styles.box2]}>
        <Text style={styles.text}>Box 2</Text>
      </View>
      <View style={[styles.box, styles.box3]}>
        <Text style={styles.text}>Box 3</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column', // 垂直布局
    justifyContent: 'space-around',
    alignItems: 'center',
    padding: 20,
  },
  box: {
    width: 80,
    height: 80,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
  },
  box1: {
    backgroundColor: '#4CAF50',
  },
  box2: {
    backgroundColor: '#2196F3',
  },
  box3: {
    backgroundColor: '#FFC107',
  },
  text: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

4. 高级布局示例

响应式布局

jsx
import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';

const { width } = Dimensions.get('window');

export default function ResponsiveLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.headerText}>Header</Text>
      </View>
      <View style={styles.content}>
        <View style={styles.sidebar}>
          <Text style={styles.sidebarText}>Sidebar</Text>
        </View>
        <View style={styles.main}>
          <Text style={styles.mainText}>Main Content</Text>
        </View>
      </View>
      <View style={styles.footer}>
        <Text style={styles.footerText}>Footer</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  header: {
    height: 60,
    backgroundColor: '#4CAF50',
    justifyContent: 'center',
    alignItems: 'center',
  },
  headerText: {
    color: '#fff',
    fontSize: 18,
    fontWeight: 'bold',
  },
  content: {
    flex: 1,
    flexDirection: 'row',
  },
  sidebar: {
    width: width * 0.3,
    backgroundColor: '#2196F3',
    justifyContent: 'center',
    alignItems: 'center',
  },
  sidebarText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
  main: {
    flex: 1,
    backgroundColor: '#f5f5f5',
    justifyContent: 'center',
    alignItems: 'center',
  },
  mainText: {
    color: '#333',
    fontSize: 16,
    fontWeight: 'bold',
  },
  footer: {
    height: 60,
    backgroundColor: '#FFC107',
    justifyContent: 'center',
    alignItems: 'center',
  },
  footerText: {
    color: '#333',
    fontSize: 18,
    fontWeight: 'bold',
  },
});

网格布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function GridLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={styles.row}>
        <View style={[styles.box, styles.box1]}>
          <Text style={styles.text}>1</Text>
        </View>
        <View style={[styles.box, styles.box2]}>
          <Text style={styles.text}>2</Text>
        </View>
        <View style={[styles.box, styles.box3]}>
          <Text style={styles.text}>3</Text>
        </View>
      </View>
      <View style={styles.row}>
        <View style={[styles.box, styles.box4]}>
          <Text style={styles.text}>4</Text>
        </View>
        <View style={[styles.box, styles.box5]}>
          <Text style={styles.text}>5</Text>
        </View>
        <View style={[styles.box, styles.box6]}>
          <Text style={styles.text}>6</Text>
        </View>
      </View>
      <View style={styles.row}>
        <View style={[styles.box, styles.box7]}>
          <Text style={styles.text}>7</Text>
        </View>
        <View style={[styles.box, styles.box8]}>
          <Text style={styles.text}>8</Text>
        </View>
        <View style={[styles.box, styles.box9]}>
          <Text style={styles.text}>9</Text>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
  },
  row: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 10,
  },
  box: {
    width: '30%',
    aspectRatio: 1,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
  },
  box1: {
    backgroundColor: '#4CAF50',
  },
  box2: {
    backgroundColor: '#2196F3',
  },
  box3: {
    backgroundColor: '#FFC107',
  },
  box4: {
    backgroundColor: '#f44336',
  },
  box5: {
    backgroundColor: '#9C27B0',
  },
  box6: {
    backgroundColor: '#FF9800',
  },
  box7: {
    backgroundColor: '#795548',
  },
  box8: {
    backgroundColor: '#607D8B',
  },
  box9: {
    backgroundColor: '#00BCD4',
  },
  text: {
    color: '#fff',
    fontSize: 24,
    fontWeight: 'bold',
  },
});

卡片布局

jsx
import React from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';

export default function CardLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <Image
          source={{ uri: 'https://via.placeholder.com/300x150' }}
          style={styles.cardImage}
        />
        <View style={styles.cardContent}>
          <Text style={styles.cardTitle}>Card Title</Text>
          <Text style={styles.cardDescription}>
            This is a sample card layout using Flexbox in React Native.
          </Text>
          <View style={styles.cardFooter}>
            <Text style={styles.cardAuthor}>Author: John Doe</Text>
            <Text style={styles.cardDate}>2024-01-01</Text>
          </View>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  card: {
    width: '100%',
    backgroundColor: '#fff',
    borderRadius: 8,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.1,
    shadowRadius: 3.84,
    elevation: 5,
    overflow: 'hidden',
  },
  cardImage: {
    width: '100%',
    height: 150,
  },
  cardContent: {
    padding: 16,
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  cardDescription: {
    fontSize: 14,
    color: '#666',
    marginBottom: 16,
  },
  cardFooter: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  cardAuthor: {
    fontSize: 12,
    color: '#999',
  },
  cardDate: {
    fontSize: 12,
    color: '#999',
  },
});

5. 常用布局模式

居中布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function CenteredLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={styles.centeredBox}>
        <Text style={styles.text}>Centered Content</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center', // 主轴居中
    alignItems: 'center', // 交叉轴居中
  },
  centeredBox: {
    width: 200,
    height: 200,
    backgroundColor: '#4CAF50',
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
  },
  text: {
    color: '#fff',
    fontSize: 18,
    fontWeight: 'bold',
  },
});

两端对齐布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function SpaceBetweenLayoutExample() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Left</Text>
      <Text style={styles.text}>Center</Text>
      <Text style={styles.text}>Right</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between', // 两端对齐
    alignItems: 'center',
    paddingHorizontal: 20,
  },
  text: {
    fontSize: 16,
    fontWeight: '500',
  },
});

等分布局

jsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function EqualDistributionLayoutExample() {
  return (
    <View style={styles.container}>
      <View style={[styles.box, styles.box1]}>
        <Text style={styles.text}>1/3</Text>
      </View>
      <View style={[styles.box, styles.box2]}>
        <Text style={styles.text}>1/3</Text>
      </View>
      <View style={[styles.box, styles.box3]}>
        <Text style={styles.text}>1/3</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  box: {
    flex: 1, // 等分布局
    justifyContent: 'center',
    alignItems: 'center',
  },
  box1: {
    backgroundColor: '#4CAF50',
  },
  box2: {
    backgroundColor: '#2196F3',
  },
  box3: {
    backgroundColor: '#FFC107',
  },
  text: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

6. 布局最佳实践

1. 使用 Flexbox 作为主要布局方式

Flexbox 是 React Native 中最灵活、最强大的布局方式,应该作为主要的布局工具。

2. 合理设置 flex 属性

  • 使用 flex: 1 让组件占据剩余空间
  • 使用 flexDirection 控制布局方向
  • 使用 justifyContentalignItems 控制对齐方式

3. 避免过度嵌套

过度嵌套会导致性能问题,尽量保持布局层次简单。

4. 使用 Dimensions API

使用 Dimensions API 获取屏幕尺寸,创建响应式布局。

jsx
import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

5. 测试不同屏幕尺寸

确保布局在不同屏幕尺寸上都能正常显示。

7. 常见问题与解决方案

问题 1:布局不居中

问题:组件无法居中显示。

解决方案

  • 确保容器设置了 justifyContent: 'center'alignItems: 'center'
  • 检查容器是否有足够的空间
  • 检查子组件是否有固定的宽度和高度

问题 2:布局溢出

问题:组件内容溢出容器。

解决方案

  • 使用 flexWrap: 'wrap' 让内容换行
  • 使用 overflow: 'hidden' 隐藏溢出内容
  • 调整组件大小或布局方式

问题 3:布局在不同屏幕尺寸上表现不一致

问题:布局在不同屏幕尺寸上显示不同。

解决方案

  • 使用相对单位(如百分比)
  • 使用 Dimensions API 获取屏幕尺寸
  • 使用 flexbox 的弹性布局特性

问题 4:性能问题

问题:布局导致性能问题。

解决方案

  • 避免过度嵌套
  • 避免在渲染过程中创建新的样式对象
  • 使用 StyleSheet.create 定义样式

8. 总结

Flex 布局是 React Native 中最核心的布局方式,它提供了一种灵活、强大的方式来排列和对齐组件。通过掌握 Flex 布局的基本概念和常用属性,可以创建出各种复杂的布局。

在实际开发中,建议:

  1. 使用 Flexbox 作为主要布局方式
  2. 合理设置 flex 属性
  3. 避免过度嵌套
  4. 使用 Dimensions API 创建响应式布局
  5. 测试不同屏幕尺寸的表现

通过不断实践和学习,你会逐渐掌握 Flex 布局的精髓,创建出更加美观、专业的移动应用界面。

© 2026 编程马·菜鸟教程 版权所有