本文涵盖 StyleSheet 基础用法、所有常用属性、Flexbox 对齐机制、Margin 系列详解,并在每个综合示例中附上 简易图解,帮助直观理解布局效果。
一、StyleSheet 基础用法
StyleSheet 是 React Native 中创建样式的官方推荐方式。
基本示例
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
const App = () => (
<View style={styles.container}>
<Text style={styles.title}>Hello React Native!</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
},
});
export default App;
核心优势
- 性能优化:样式通过 ID 引用,避免内联样式的重复创建。
- 代码可维护性:样式集中管理,支持复用和类型检查(TypeScript)。
- 开发体验:自动补全和错误提示。
常用 API
| 方法 | 作用 |
|---|---|
StyleSheet.create(styles) |
创建样式表(最常用) |
StyleSheet.flatten(styles) |
合并样式数组为单个对象(调试用) |
StyleSheet.absoluteFillObject |
绝对定位填充父容器 |
StyleSheet.hairlineWidth |
平台支持的最细边框宽度 |
二、常用样式属性完整列表
以下按功能分类,列出 React Native 中最常用的样式属性。
1. 布局与 Flexbox
| 属性 | 解释 | 值描述 |
|---|---|---|
flex |
组件在父容器中的弹性权重,决定剩余空间的分配比例。 |
0(默认,不伸缩);正数(如 1、2)按比例分配剩余空间。 |
flexDirection |
主轴方向,决定子组件的排列顺序。 |
'column'(默认,垂直从上到下)、'row'(水平从左到右)、'column-reverse'、'row-reverse'。 |
justifyContent |
子组件在主轴上的对齐方式。 |
'flex-start'(默认)、'flex-end'、'center'、'space-between'、'space-around'、'space-evenly'。 |
alignItems |
子组件在交叉轴上的对齐方式。 |
'stretch'(默认)、'flex-start'、'flex-end'、'center'、'baseline'。 |
alignSelf |
覆盖父容器的 alignItems。 |
同 alignItems,外加 'auto'(默认)。 |
flexWrap |
主轴空间不足时是否换行。 |
'nowrap'(默认)、'wrap'、'wrap-reverse'。 |
2. 尺寸与位置
| 属性 | 解释 | 值描述 |
|---|---|---|
width / height
|
固定宽度或高度。 |
number(逻辑像素)、string(百分比,如 '50%')、'auto'。 |
minWidth / minHeight 等 |
限制尺寸的最小/最大值。 | 同 width/height。 |
position |
定位类型。 |
'relative'(默认)、'absolute'。 |
top / bottom / left / right
|
定位偏移量。 |
number、string(百分比)。 |
3. 间距(Margin & Padding)
| 属性 | 解释 | 值描述 |
|---|---|---|
margin |
四个方向外边距相同。 |
number 或 string(百分比,相对父容器宽度)。 |
marginTop / marginBottom 等 |
单方向外边距。 | 同上。 |
marginHorizontal |
左、右外边距相同。 | 同上。 |
marginVertical |
上、下外边距相同。 | 同上。 |
padding 及其方向 |
内边距,用法同 margin。 | 同上(无 'auto' 值)。 |
特殊值:'auto' 仅对水平 margin 有效(用于居中);负边距使元素反向移动。
4. 背景与边框
| 属性 | 解释 | 值描述 |
|---|---|---|
backgroundColor |
背景颜色。 | 颜色字符串:'red'、'#f00'、'rgba(255,0,0,0.5)' 等。 |
borderWidth / borderColor
|
边框宽度/颜色。 | 宽度:number;颜色:颜色字符串。 |
borderRadius |
圆角半径。 |
number 或 string(百分比)。 |
borderStyle |
边框线条样式。 |
'solid'、'dotted'、'dashed'。 |
5. 文本样式(适用于 Text 组件)
| 属性 | 解释 | 值描述 |
|---|---|---|
color |
文字颜色。 | 颜色字符串。 |
fontSize |
字体大小。 |
number,默认 14。 |
fontWeight |
字体粗细。 |
'normal'、'bold'、'100'~'900'。 |
fontFamily |
字体族名称。 |
string,如 'Arial'。 |
textAlign |
文字水平对齐。 |
'auto'、'left'、'center'、'right'、'justify'。 |
lineHeight |
行高。 |
number。 |
textDecorationLine |
文字修饰线。 |
'none'、'underline'、'line-through'。 |
textTransform |
大小写转换。 |
'none'、'uppercase'、'lowercase'、'capitalize'。 |
letterSpacing |
字符间距。 |
number。 |
6. 阴影与变换
| 属性 | 解释 | 值描述 |
|---|---|---|
shadowColor / shadowOffset 等 |
iOS 阴影。 | 颜色、偏移量 {width,height}、不透明度 0~1、模糊半径。 |
elevation |
Android 阴影深度。 |
number(0~24)。 |
transform |
2D/3D 变换。 | 数组,如 [{ scale: 2 }, { rotate: '45deg' }]。 |
opacity |
整体不透明度。 |
0 ~ 1。 |
aspectRatio |
强制宽高比。 |
number,如 16/9。 |
三、深入理解 justifyContent 与 alignItems
这两个属性容易混淆,关键在于理解 主轴 和 交叉轴 的概念。
核心规则
-
主轴方向由
flexDirection决定:-
flexDirection: 'column'(默认)→ 主轴为垂直方向(上下)。 -
flexDirection: 'row'→ 主轴为水平方向(左右)。
-
-
justifyContent控制子组件在 主轴 上的对齐。 -
alignItems控制子组件在 交叉轴 上的对齐。
图解
默认 (flexDirection: 'column')
┌─────────────────────┐
│ │
│ 主轴 (垂直) │
│ ↑ justifyContent │
│ │
│ ← alignItems → │ 交叉轴 (水平)
│ │
└─────────────────────┘
flexDirection: 'row'
┌─────────────────────┐
│ ← justifyContent → │ 主轴 (水平)
│ │
│ ↑ alignItems │ 交叉轴 (垂直)
│ ↓ │
└─────────────────────┘
示例代码
// 情况1:默认 column,实现水平垂直居中
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>我位于正中央</Text>
</View>
// 情况2:row 模式,同样实现水平垂直居中
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
<Text>我也在正中央</Text>
</View>
口诀:justifyContent 跟着 flexDirection 走,alignItems 负责另一个方向。
四、Margin 系列完整详解
属性总表
| 属性 | 解释 | 值的描述 |
|---|---|---|
margin |
四个方向外边距相同。 |
number 或 string(百分比,相对父容器宽度)。 |
marginTop / marginBottom
|
上/下外边距。 | 同上。 |
marginLeft / marginRight
|
左/右外边距。 | 同上。 |
marginHorizontal |
左、右外边距相同。 | 同上。 |
marginVertical |
上、下外边距相同。 | 同上。 |
特殊说明
-
百分比参照:所有方向的百分比外边距都相对于父容器的宽度(包括
marginTop)。 -
auto值:仅对水平方向有效(marginLeft/marginRight),用于水平居中。 - 负边距:允许负值,会使组件反向移动并可能覆盖其他元素。
-
边距叠加:垂直方向上相邻组件的
marginBottom和marginTop不会叠加,取最大值。
margin 不会影响组件自身的尺寸。下面用两个简洁的图解说明。
- 图解 1:
margin只加外部空间,不改变组件大小
组件自身尺寸固定 (100x100)
┌─────────────────────────────────────┐
│ ← 20 → ┌───────────┐ ← 20 → │
│ ↑ │ │ ↑ │
│ 20 │ 100x100 │ 20 │
│ ↓ │ 红色区域 │ ↓ │
│ └───────────┘ │
│ ← 20 → │
└─────────────────────────────────────┘
总占位 = 140x140,但红色区域仍是 100x100
- 图解 2:
marginvspadding对尺寸的影响
margin(不影响自身尺寸) padding(会增加自身尺寸)
┌─────────────────┐ ┌─────────────────┐
│ 外部空白 │ │ ┌───────────┐ │
│ ┌───────────┐ │ │ │ │ │
│ │ 100x100 │ │ │ │ 100x100 │ │
│ │ 组件 │ │ │ │ 内容区 │ │
│ └───────────┘ │ │ │ │ │
│ 外部空白 │ │ └───────────┘ │
└─────────────────┘ └─────────────────┘
组件自身仍是 100x100 总尺寸 = 100 + padding*2
-
左侧 (
margin):红色框大小不变,只是周围多了透明空间。 -
右侧 (
padding):红色框会向外扩展,组件整体变大。
使用示例
const styles = StyleSheet.create({
box: {
margin: 20, // 四个方向 20
},
card: {
marginHorizontal: 16, // 左右 16
marginVertical: 8, // 上下 8
},
centered: {
width: 200,
marginLeft: 'auto', // 水平居中
marginRight: 'auto',
},
negative: {
marginTop: -10, // 向上移动 10
},
});
五、综合代码示例(含简易图解)
示例 1:基础卡片组件
图解:
┌─────────────────────────────┐
│ ┌───────────────────────┐ │
│ │ 标题 (加粗, 大字号) │ │
│ │ 内容文字, 灰色, 行高20 │ │
│ │ ───────────────────── │ │
│ │ 👍 点赞 💬 评论 │ │
│ └───────────────────────┘ │
│ (卡片外部有阴影和圆角) │
└─────────────────────────────┘
代码:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const Card = ({ title, content }) => (
<View style={styles.card}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.content}>{content}</Text>
<View style={styles.footer}>
<Text style={styles.footerText}>👍 点赞</Text>
<Text style={styles.footerText}>💬 评论</Text>
</View>
</View>
);
const styles = StyleSheet.create({
card: {
width: '90%',
marginVertical: 12,
padding: 16,
backgroundColor: '#fff',
borderRadius: 12,
borderWidth: 1,
borderColor: '#e0e0e0',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
marginBottom: 8,
},
content: {
fontSize: 14,
color: '#666',
lineHeight: 20,
marginBottom: 12,
},
footer: {
flexDirection: 'row',
justifyContent: 'space-around',
borderTopWidth: 1,
borderTopColor: '#eee',
paddingTop: 10,
},
footerText: {
fontSize: 14,
color: '#888',
},
});
示例 2:Flexbox 三列布局
图解:
┌─────────────────────────────────┐
│ 顶部导航栏 (60px) │
├────────┬────────────┬───────────┤
│ 菜单 │ 内容区域 │ 广告 │
│ 80px │ flex:1 │ 70px │
│ 背景浅橙│ 背景浅黄 │ 背景浅橙红 │
├────────┴────────────┴───────────┤
│ 首页 发现 我的 │
│ (三个按钮等宽,底部栏60px) │
└─────────────────────────────────┘
代码:
const FlexboxDemo = () => (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Flexbox 布局</Text>
</View>
<View style={styles.main}>
<View style={styles.left}><Text>菜单</Text></View>
<View style={styles.center}><Text>内容区域</Text></View>
<View style={styles.right}><Text>广告</Text></View>
</View>
<View style={styles.footer}>
<View style={styles.button}><Text>首页</Text></View>
<View style={styles.button}><Text>发现</Text></View>
<View style={styles.button}><Text>我的</Text></View>
</View>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5' },
header: { height: 60, backgroundColor: '#6200ee', justifyContent: 'center', alignItems: 'center' },
headerText: { color: 'white', fontSize: 18, fontWeight: 'bold' },
main: { flex: 1, flexDirection: 'row' },
left: { width: 80, backgroundColor: '#ffcc80', alignItems: 'center', paddingTop: 20 },
center: { flex: 1, backgroundColor: '#fff9c4', justifyContent: 'center', alignItems: 'center' },
right: { width: 70, backgroundColor: '#ffab91', alignItems: 'center', paddingTop: 20 },
footer: { height: 60, flexDirection: 'row', justifyContent: 'space-evenly', alignItems: 'center', backgroundColor: '#fff', borderTopWidth: 1, borderTopColor: '#ddd' },
button: { flex: 1, alignItems: 'center' },
});
示例 3:文本样式大全
图解:
┌─────────────────────────────────┐
│ 基础文字 (默认大小16) │
│ 大号加粗文字 (24, bold) │
│ 彩色+背景文字 (红字黄底) │
│ 下划线文字 │
│ 删除线文字 │
│ HELLO WORLD (转大写) │
│ 字 间 距 加 大 (letterSpacing)│
│ 一段多行文本,行高28,两端对齐, │
│ 看起来更舒适。 │
└─────────────────────────────────┘
代码:
const TextStylesDemo = () => (
<View style={{ flex: 1, padding: 20, backgroundColor: '#f0f0f0' }}>
<Text style={{ fontSize: 16, marginBottom: 12 }}>基础文字</Text>
<Text style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 12 }}>大号加粗</Text>
<Text style={{ fontSize: 18, color: '#d32f2f', backgroundColor: '#ffeb3b', marginBottom: 12 }}>彩色+背景</Text>
<Text style={{ fontSize: 16, textDecorationLine: 'underline', marginBottom: 12 }}>下划线</Text>
<Text style={{ fontSize: 16, textDecorationLine: 'line-through', marginBottom: 12 }}>删除线</Text>
<Text style={{ fontSize: 16, textTransform: 'uppercase', marginBottom: 12 }}>hello world</Text>
<Text style={{ fontSize: 18, letterSpacing: 4, marginBottom: 12 }}>字间距加大</Text>
<Text style={{ fontSize: 16, lineHeight: 28, textAlign: 'justify' }}>这是一段多行文本,行高28,两端对齐。通过调整行高和字间距,可以让长篇文字阅读起来更舒适。</Text>
</View>
);
示例 4:绝对定位 + 变换(悬浮按钮)
图解:
┌─────────────────────────────────┐
│ │
│ 普通页面内容 │
│ 这里是一些文字... │
│ │
│ │
│ ┌────┐ │
│ │ + │ │ ← 悬浮按钮 (右下角)
│ └────┘ │ 绝对定位,旋转45度
└─────────────────────────────────┘
代码:
import { TouchableOpacity } from 'react-native';
const AbsoluteDemo = () => (
<View style={{ flex: 1, padding: 20, backgroundColor: '#e8eaf6' }}>
<Text style={{ fontSize: 16, marginBottom: 16 }}>这是一个普通页面,右下角有一个悬浮按钮。</Text>
<Text style={{ fontSize: 16, marginBottom: 16 }}>该按钮使用了绝对定位和旋转变换。</Text>
<TouchableOpacity style={styles.fab} onPress={() => alert('点击悬浮按钮')}>
<Text style={styles.fabText}>+</Text>
</TouchableOpacity>
</View>
);
const styles = StyleSheet.create({
fab: {
position: 'absolute',
bottom: 20,
right: 20,
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: '#7c4dff',
justifyContent: 'center',
alignItems: 'center',
transform: [{ rotate: '45deg' }], // 整个按钮旋转45度
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 5,
elevation: 6,
},
fabText: {
fontSize: 32,
color: 'white',
fontWeight: 'bold',
transform: [{ rotate: '45deg' }], // 内部文字再旋转45度,使加号保持正向
},
});
六、总结与最佳实践
-
优先使用
StyleSheet.create(),避免内联样式(动态样式除外)。 -
理解 Flexbox:牢记主轴与交叉轴,
justifyContent和alignItems各司其职。 -
间距管理:优先使用
marginBottom或marginTop之一,避免叠加混淆;利用marginHorizontal: 'auto'实现水平居中。 -
注意平台差异:阴影用
shadow*(iOS)和elevation(Android);overflow在 Android 上支持有限。 -
性能提示:静态样式放在
StyleSheet中;动态样式(如根据状态改变颜色)才用内联。
这份指南涵盖了 React Native 样式开发的核心知识,每个示例都配有图解,帮助您直观理解布局效果。