React Native 鸿蒙跨平台开发:Flexbox 弹性布局代码指南
/ Flexbox 相关的样式属性类型flex?: number;alignItems?alignSelf?flexWrap?flexGrow?: number;flexShrink?: number;flexBasis?gap?rowGap?columnGap?
·
51. React Native 鸿蒙跨平台开发:Flexbox 弹性布局代码指南
一、核心知识点:Flexbox 弹性布局完整核心用法
1. 用到的纯内置组件与 API
所有能力均为 RN 原生自带,全部从 react-native 核心包直接导入,无任何额外依赖、无任何第三方库,鸿蒙端无任何兼容问题,也是实现 Flexbox 弹性布局的全部核心能力,零基础易理解、易复用,无任何冗余,所有 Flexbox 弹性布局功能均基于以下组件/API 原生实现:
| 核心组件/API | 作用说明 | 鸿蒙适配特性 |
|---|---|---|
View |
核心容器组件,实现所有「弹性布局容器」,支持 flex、flexDirection、justifyContent、alignItems、alignSelf、flexWrap、flexGrow、flexShrink、flexBasis、gap 等所有 Flexbox 属性 | ✅ 鸿蒙端 Flexbox 布局渲染无错位,所有属性完美生效 |
Text |
文本组件,显示布局示例和说明 | ✅ 鸿蒙端文本渲染正常,支持多行文本 |
StyleSheet |
原生样式管理,编写鸿蒙端最优的 Flexbox 样式:弹性容器样式、对齐样式、间距样式,无任何不兼容CSS属性 | ✅ 贴合鸿蒙官方视觉设计规范,颜色、圆角、间距均为真机实测最优值 |
SafeAreaView |
安全区域容器,适配刘海屏等异形屏 | ✅ 鸿蒙端安全区域适配正常 |
ScrollView |
滚动容器,支持 flex 布局的滚动内容 | ✅ 鸿蒙端滚动正常 |
二、深入理解 Flexbox 弹性布局
1. Flexbox 是什么?
Flexbox(Flexible Box)是一种一维布局模型,用于在容器中高效地分配空间和对齐子元素。React Native 实现了 Flexbox 布局系统的核心子集,与 Web 端的 Flexbox 非常相似,但有一些差异。
2. 为什么需要 Flexbox?
在移动应用开发中,我们需要一种灵活、高效的布局方式来适应不同屏幕尺寸和方向。Flexbox 提供了以下优势:
- 响应式布局:自动适应不同屏幕尺寸
- 灵活对齐:轻松实现水平和垂直对齐
- 空间分配:自动分配剩余空间
- 方向控制:支持横向和纵向布局
- 简化代码:减少嵌套层级,提高可读性
3. Flexbox 的核心概念
Flexbox 布局基于两个核心概念:
- Flex 容器(Flex Container):设置了
display: flex的父元素 - Flex 子项(Flex Items):Flex 容器的直接子元素
4. Flexbox 的类型定义
// Flexbox 相关的样式属性类型
interface FlexStyle {
flex?: number;
flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse';
flexGrow?: number;
flexShrink?: number;
flexBasis?: number | string;
gap?: number | string;
rowGap?: number | string;
columnGap?: number | string;
}
三、Flexbox 容器属性详解
1. flexDirection - 主轴方向
控制 Flex 容器的主轴方向,决定子元素的排列方向。
// 横向排列(默认)
<View style={{ flexDirection: 'row' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 纵向排列
<View style={{ flexDirection: 'column' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 横向反向排列
<View style={{ flexDirection: 'row-reverse' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 纵向反向排列
<View style={{ flexDirection: 'column-reverse' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
取值说明:
row:横向排列,从左到右(默认)column:纵向排列,从上到下row-reverse:横向反向排列,从右到左column-reverse:纵向反向排列,从下到上
2. justifyContent - 主轴对齐
控制子元素在主轴上的对齐方式。
// 起始对齐(默认)
<View style={{ flexDirection: 'row', justifyContent: 'flex-start' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 结束对齐
<View style={{ flexDirection: 'row', justifyContent: 'flex-end' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 居中对齐
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 两端对齐
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 环绕对齐
<View style={{ flexDirection: 'row', justifyContent: 'space-around' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 均匀对齐
<View style={{ flexDirection: 'row', justifyContent: 'space-evenly' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
取值说明:
flex-start:起始对齐(默认)flex-end:结束对齐center:居中对齐space-between:两端对齐,子元素之间间距相等space-around:环绕对齐,子元素两侧间距相等space-evenly:均匀对齐,所有间距相等
3. alignItems - 交叉轴对齐
控制子元素在交叉轴上的对齐方式。
// 起始对齐(默认)
<View style={{ flexDirection: 'row', alignItems: 'flex-start' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, { height: 60 }]}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 结束对齐
<View style={{ flexDirection: 'row', alignItems: 'flex-end' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, { height: 60 }]}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 居中对齐
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, { height: 60 }]}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 拉伸对齐
<View style={{ flexDirection: 'row', alignItems: 'stretch' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, { height: 60 }]}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
取值说明:
flex-start:起始对齐(默认)flex-end:结束对齐center:居中对齐stretch:拉伸对齐,子元素拉伸填满交叉轴baseline:基线对齐(文本基线)
4. flexWrap - 换行控制
控制子元素是否换行。
// 不换行(默认)
<View style={{ flexDirection: 'row', flexWrap: 'nowrap' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
<View style={styles.box}><Text>4</Text></View>
<View style={styles.box}><Text>5</Text></View>
</View>
// 换行
<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
<View style={styles.box}><Text>4</Text></View>
<View style={styles.box}><Text>5</Text></View>
</View>
// 反向换行
<View style={{ flexDirection: 'row', flexWrap: 'wrap-reverse' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
<View style={styles.box}><Text>4</Text></View>
<View style={styles.box}><Text>5</Text></View>
</View>
取值说明:
nowrap:不换行(默认)wrap:换行wrap-reverse:反向换行
5. gap - 间距控制
控制子元素之间的间距。
// 统一间距
<View style={{ flexDirection: 'row', gap: 10 }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
</View>
// 行间距和列间距
<View style={{ flexDirection: 'row', flexWrap: 'wrap', rowGap: 10, columnGap: 20 }}>
<View style={styles.box}><Text>1</Text></View>
<View style={styles.box}><Text>2</Text></View>
<View style={styles.box}><Text>3</Text></View>
<View style={styles.box}><Text>4</Text></View>
<View style={styles.box}><Text>5</Text></View>
</View>
取值说明:
gap:统一间距,同时设置行间距和列间距rowGap:行间距columnGap:列间距
四、Flexbox 子项属性详解
1. flex - 弹性比例
控制子元素的弹性比例,决定如何分配剩余空间。
// 等比例分配
<View style={{ flexDirection: 'row' }}>
<View style={[styles.box, { flex: 1 }]}><Text>1</Text></View>
<View style={[styles.box, { flex: 1 }]}><Text>2</Text></View>
<View style={[styles.box, { flex: 1 }]}><Text>3</Text></View>
</View>
// 不同比例分配
<View style={{ flexDirection: 'row' }}>
<View style={[styles.box, { flex: 1 }]}><Text>1</Text></View>
<View style={[styles.box, { flex: 2 }]}><Text>2</Text></View>
<View style={[styles.box, { flex: 1 }]}><Text>3</Text></View>
</View>
// 固定宽度 + 弹性
<View style={{ flexDirection: 'row' }}>
<View style={[styles.box, { width: 60 }]}><Text>1</Text></View>
<View style={[styles.box, { flex: 1 }]}><Text>2</Text></View>
<View style={[styles.box, { width: 60 }]}><Text>3</Text></View>
</View>
取值说明:
flex: 1:占据所有可用空间flex: 2:占据两倍可用空间flex: 0:不占据可用空间(固定大小)
2. alignSelf - 独立对齐
控制单个子元素的对齐方式,覆盖容器的 alignItems。
<View style={{ flexDirection: 'row', alignItems: 'flex-start' }}>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, { alignSelf: 'center' }]}><Text>2</Text></View>
<View style={[styles.box, { alignSelf: 'flex-end' }]}><Text>3</Text></View>
</View>
取值说明:
auto:继承容器的alignItems(默认)flex-start:起始对齐flex-end:结束对齐center:居中对齐stretch:拉伸对齐baseline:基线对齐
3. flexGrow - 扩展比例
控制子元素的扩展比例。
<View style={{ flexDirection: 'row' }}>
<View style={[styles.box, { flexGrow: 0 }]}><Text>1</Text></View>
<View style={[styles.box, { flexGrow: 1 }]}><Text>2</Text></View>
<View style={[styles.box, { flexGrow: 2 }]}><Text>3</Text></View>
</View>
取值说明:
flexGrow: 0:不扩展(默认)flexGrow: 1:扩展flexGrow: 2:扩展两倍
五、实战完整版:企业级通用 Flexbox 弹性布局
import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
SafeAreaView,
ScrollView,
} from 'react-native';
// Flexbox 弹性布局演示
const FlexboxScreen = () => {
const [alignItems, setAlignItems] = useState<'flex-start' | 'center' | 'flex-end' | 'stretch'>('flex-start');
const [justifyContent, setJustifyContent] = useState<'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'>('flex-start');
const [flexDirection, setFlexDirection] = useState<'row' | 'column'>('row');
const alignItemsOptions = [
{ value: 'flex-start', label: 'flex-start', description: '起始对齐' },
{ value: 'center', label: 'center', description: '居中对齐' },
{ value: 'flex-end', label: 'flex-end', description: '结束对齐' },
{ value: 'stretch', label: 'stretch', description: '拉伸对齐' },
];
const justifyContentOptions = [
{ value: 'flex-start', label: 'flex-start', description: '起始对齐' },
{ value: 'center', label: 'center', description: '居中对齐' },
{ value: 'flex-end', label: 'flex-end', description: '结束对齐' },
{ value: 'space-between', label: 'space-between', description: '两端对齐' },
{ value: 'space-around', label: 'space-around', description: '环绕对齐' },
{ value: 'space-evenly', label: 'space-evenly', description: '均匀对齐' },
];
const flexDirectionOptions = [
{ value: 'row', label: 'row', description: '水平布局' },
{ value: 'column', label: 'column', description: '垂直布局' },
];
return (
<SafeAreaView style={styles.container}>
{/* 标题区域 */}
<View style={styles.header}>
<Text style={styles.pageTitle}>React Native for Harmony</Text>
<Text style={styles.subtitle}>Flexbox 弹性布局</Text>
</View>
{/* 内容区域 */}
<ScrollView style={styles.content}>
{/* flexDirection 选择 */}
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.cardTitle}>flexDirection - 主轴方向</Text>
</View>
<View style={styles.cardBody}>
<Text style={styles.currentValue}>当前: {flexDirection}</Text>
<View style={styles.buttonRow}>
{flexDirectionOptions.map((option) => (
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
flexDirection === option.value && styles.optionButtonActive,
]}
onPress={() => setFlexDirection(option.value as any)}
>
<Text style={[
styles.optionButtonText,
flexDirection === option.value && styles.optionButtonTextActive,
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</View>
{/* justifyContent 选择 */}
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.cardTitle}>justifyContent - 主轴对齐</Text>
</View>
<View style={styles.cardBody}>
<Text style={styles.currentValue}>当前: {justifyContent}</Text>
<View style={styles.buttonRow}>
{justifyContentOptions.map((option) => (
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
justifyContent === option.value && styles.optionButtonActive,
]}
onPress={() => setJustifyContent(option.value as any)}
>
<Text style={[
styles.optionButtonText,
justifyContent === option.value && styles.optionButtonTextActive,
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</View>
{/* alignItems 选择 */}
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.cardTitle}>alignItems - 交叉轴对齐</Text>
</View>
<View style={styles.cardBody}>
<Text style={styles.currentValue}>当前: {alignItems}</Text>
<View style={styles.buttonRow}>
{alignItemsOptions.map((option) => (
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
alignItems === option.value && styles.optionButtonActive,
]}
onPress={() => setAlignItems(option.value as any)}
>
<Text style={[
styles.optionButtonText,
alignItems === option.value && styles.optionButtonTextActive,
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</View>
{/* 演示区域 */}
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.cardTitle}>实时预览</Text>
</View>
<View style={styles.cardBody}>
<View
style={[
styles.previewContainer,
{
flexDirection,
justifyContent,
alignItems,
},
]}
>
<View style={styles.previewItem}>
<Text style={styles.previewText}>1</Text>
</View>
<View style={styles.previewItem}>
<Text style={styles.previewText}>2</Text>
</View>
<View style={styles.previewItem}>
<Text style={styles.previewText}>3</Text>
</View>
</View>
<View style={styles.codePreview}>
<Text style={styles.codeText}>
flexDirection: "{flexDirection}"{'\n'}
justifyContent: "{justifyContent}"{'\n'}
alignItems: "{alignItems}"
</Text>
</View>
</View>
</View>
{/* 说明区域 */}
<View style={styles.infoCard}>
<Text style={styles.infoTitle}>💡 属性说明</Text>
<Text style={styles.infoText}>• flexDirection: 主轴方向(row: 水平, column: 垂直)</Text>
<Text style={styles.infoText}>• justifyContent: 主轴对齐方式</Text>
<Text style={styles.infoText}>• alignItems: 交叉轴对齐方式</Text>
<Text style={styles.infoText}>• 点击按钮切换不同布局效果</Text>
<Text style={styles.infoText}>• 鸿蒙端完美兼容,交互流畅</Text>
</View>
</ScrollView>
</SafeAreaView>
);
};
const App = () => {
return <FlexboxScreen />;
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5F7FA',
},
// ======== 标题区域 ========
header: {
padding: 20,
backgroundColor: '#FFFFFF',
borderBottomWidth: 1,
borderBottomColor: '#EBEEF5',
},
pageTitle: {
fontSize: 24,
fontWeight: '700',
color: '#303133',
textAlign: 'center',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
fontWeight: '500',
color: '#909399',
textAlign: 'center',
},
// ======== 内容区域 ========
content: {
flex: 1,
padding: 16,
},
// ======== 卡片样式 ========
card: {
backgroundColor: '#FFFFFF',
borderRadius: 12,
marginBottom: 16,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.08,
shadowRadius: 8,
elevation: 4,
},
cardHeader: {
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#EBEEF5',
},
cardTitle: {
fontSize: 18,
fontWeight: '600',
color: '#303133',
},
cardBody: {
padding: 16,
},
// ======== 当前值显示 ========
currentValue: {
fontSize: 14,
color: '#606266',
marginBottom: 12,
textAlign: 'center',
},
// ======== 按钮行 ========
buttonRow: {
flexDirection: 'row',
flexWrap: 'wrap',
marginBottom: 8,
},
// ======== 选项按钮 ========
optionButton: {
backgroundColor: '#F5F7FA',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 6,
marginRight: 8,
marginBottom: 8,
borderWidth: 1,
borderColor: '#DCDFE6',
},
optionButtonActive: {
backgroundColor: '#409EFF',
borderColor: '#409EFF',
},
optionButtonText: {
fontSize: 12,
color: '#606266',
fontWeight: '500',
},
optionButtonTextActive: {
color: '#FFFFFF',
},
// ======== 预览容器 ========
previewContainer: {
backgroundColor: '#F5F7FA',
borderRadius: 8,
padding: 20,
minHeight: 150,
marginBottom: 16,
},
previewItem: {
width: 60,
height: 60,
backgroundColor: '#409EFF',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
margin: 8,
},
previewText: {
fontSize: 24,
fontWeight: '700',
color: '#FFFFFF',
},
// ======== 代码预览 ========
codePreview: {
backgroundColor: '#2D2D2D',
borderRadius: 8,
padding: 12,
},
codeText: {
fontSize: 12,
color: '#00FF00',
fontFamily: 'monospace',
},
// ======== 信息卡片 ========
infoCard: {
backgroundColor: '#FFFFFF',
borderRadius: 12,
padding: 16,
margin: 16,
marginTop: 0,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.08,
shadowRadius: 8,
elevation: 4,
},
infoTitle: {
fontSize: 16,
fontWeight: '600',
color: '#303133',
marginBottom: 12,
},
infoText: {
fontSize: 14,
color: '#606266',
lineHeight: 22,
marginBottom: 6,
},
});
export default App;

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)