React Native 常用样式指南

本文将详细介绍React Native中的常用样式属性、最佳实践和现代样式解决方案,帮助开发者快速构建美观、响应式的移动应用界面。

1. 基础样式属性

1.1 View样式

属性 类型 描述 示例
backfaceVisibility enum(‘visible’, ‘hidden’) 背面可见性 backfaceVisibility: 'hidden'
backgroundColor string 背景颜色 backgroundColor: '#FFFFFF'
borderColor string 边框颜色 borderColor: '#E0E0E0'
borderTopColor string 上边框颜色 borderTopColor: '#FF0000'
borderRightColor string 右边框颜色 borderRightColor: '#00FF00'
borderBottomColor string 下边框颜色 borderBottomColor: '#0000FF'
borderLeftColor string 左边框颜色 borderLeftColor: '#FFFF00'
borderRadius number 边框圆角半径 borderRadius: 8
borderTopLeftRadius number 左上角圆角半径 borderTopLeftRadius: 12
borderTopRightRadius number 右上角圆角半径 borderTopRightRadius: 12
borderBottomLeftRadius number 左下角圆角半径 borderBottomLeftRadius: 12
borderBottomRightRadius number 右下角圆角半径 borderBottomRightRadius: 12
borderStyle enum(‘solid’, ‘dotted’, ‘dashed’) 边框样式 borderStyle: 'dashed'
borderWidth number 边框宽度 borderWidth: 1
borderTopWidth number 上边框宽度 borderTopWidth: 2
borderRightWidth number 右边框宽度 borderRightWidth: 2
borderBottomWidth number 下边框宽度 borderBottomWidth: 2
borderLeftWidth number 左边框宽度 borderLeftWidth: 2
opacity number 不透明度 (0-1) opacity: 0.5
overflow enum(‘visible’, ‘hidden’) 内容溢出处理 overflow: 'hidden'
testID string 测试ID testID: 'login-button'

1.2 Image样式

属性 类型 描述 示例
resizeMode enum(‘cover’, ‘contain’, ‘stretch’, ‘center’, ‘repeat’) 图片调整模式 resizeMode: 'cover'
backgroundColor string 背景颜色 backgroundColor: '#F0F0F0'
borderColor string 边框颜色 borderColor: '#E0E0E0'
borderWidth number 边框宽度 borderWidth: 1
borderRadius number 边框圆角半径 borderRadius: 8
overflow enum(‘visible’, ‘hidden’) 内容溢出处理 overflow: 'hidden'
tintColor string 图片着色 tintColor: '#FF5722'
opacity number 不透明度 (0-1) opacity: 0.8

1.3 Text样式

属性 类型 描述 示例
color string 字体颜色 color: '#333333'
fontFamily string 字体家族 fontFamily: 'System'
fontSize number 字体大小 fontSize: 16
fontStyle enum(‘normal’, ‘italic’) 字体样式 fontStyle: 'italic'
fontWeight enum(‘normal’, ‘bold’, ‘100’, ‘200’, ‘300’, ‘400’, ‘500’, ‘600’, ‘700’, ‘800’, ‘900’) 字体粗细 fontWeight: '600'
letterSpacing number 字间距 letterSpacing: 0.5
lineHeight number 行间距 lineHeight: 24
textAlign enum(‘auto’, ‘left’, ‘right’, ‘center’, ‘justify’) 文本对齐方式 textAlign: 'center'
textAlignVertical enum(‘auto’, ‘top’, ‘bottom’, ‘center’) 垂直对齐方式 textAlignVertical: 'center'
textDecorationLine enum(‘none’, ‘underline’, ‘line-through’, ‘underline line-through’) 文本装饰线 textDecorationLine: 'underline'
textDecorationColor string 文本装饰线颜色 textDecorationColor: '#FF0000'
textDecorationStyle enum(‘solid’, ‘double’, ‘dotted’, ‘dashed’, ‘wavy’) 文本装饰线样式 textDecorationStyle: 'dashed'
textTransform enum(‘none’, ‘capitalize’, ‘uppercase’, ‘lowercase’) 文本转换 textTransform: 'uppercase'

1.4 Flexbox布局

属性 类型 描述 示例
width number 宽度 width: 200
height number 高度 height: 100
flex number 弹性伸缩 flex: 1
flexDirection enum(‘row’, ‘column’, ‘row-reverse’, ‘column-reverse’) 弹性方向 flexDirection: 'row'
flexWrap enum(‘wrap’, ‘nowrap’, ‘wrap-reverse’) 弹性换行 flexWrap: 'wrap'
justifyContent enum(‘flex-start’, ‘flex-end’, ‘center’, ‘space-between’, ‘space-around’, ‘space-evenly’) 主轴对齐 justifyContent: 'space-between'
alignItems enum(‘flex-start’, ‘flex-end’, ‘center’, ‘stretch’, ‘baseline’) 交叉轴对齐 alignItems: 'center'
alignSelf enum(‘auto’, ‘flex-start’, ‘flex-end’, ‘center’, ‘stretch’, ‘baseline’) 自身对齐 alignSelf: 'flex-end'
flexGrow number 弹性增长 flexGrow: 1
flexShrink number 弹性收缩 flexShrink: 1
flexBasis number 弹性基础大小 flexBasis: 100

1.5 边距和内边距

属性 类型 描述 示例
margin number 外边距 margin: 10
marginTop number 上外边距 marginTop: 10
marginRight number 右外边距 marginRight: 10
marginBottom number 下外边距 marginBottom: 10
marginLeft number 左外边距 marginLeft: 10
marginHorizontal number 水平外边距 marginHorizontal: 15
marginVertical number 垂直外边距 marginVertical: 15
padding number 内边距 padding: 10
paddingTop number 上内边距 paddingTop: 10
paddingRight number 右内边距 paddingRight: 10
paddingBottom number 下内边距 paddingBottom: 10
paddingLeft number 左内边距 paddingLeft: 10
paddingHorizontal number 水平内边距 paddingHorizontal: 15
paddingVertical number 垂直内边距 paddingVertical: 15

1.6 定位

属性 类型 描述 示例
position enum(‘absolute’, ‘relative’) 定位类型 position: 'absolute'
top number 顶部位置 top: 20
right number 右侧位置 right: 20
bottom number 底部位置 bottom: 20
left number 左侧位置 left: 20

1.7 变换

属性 类型 描述 示例
transform array 变换数组 transform: [{ rotate: '45deg' }, { scale: 0.8 }]
transformMatrix array 变换矩阵 transformMatrix: [1, 0, 0, 1, 0, 0]

2. 现代样式解决方案

2.1 使用样式库

2.1.1 styled-components

1
npm install styled-components
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import styled from 'styled-components/native';

const Container = styled.View`
flex: 1;
background-color: #f5f5f5;
padding: 20px;
`;

const Title = styled.Text`
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 16px;
`;

const Button = styled.TouchableOpacity`
background-color: #007AFF;
padding: 12px;
border-radius: 8px;
align-items: center;
`;

const ButtonText = styled.Text`
color: white;
font-size: 16px;
font-weight: 600;
`;

// 使用
<Container>
<Title>欢迎使用 styled-components</Title>
<Button onPress={() => console.log('Pressed')}>
<ButtonText>点击我</ButtonText>
</Button>
</Container>

2.1.2 NativeBase

1
npm install native-base
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Container, Header, Title, Content, Button, Text } from 'native-base';

// 使用
<Container>
<Header>
<Title>NativeBase 示例</Title>
</Header>
<Content padder>
<Text>欢迎使用 NativeBase</Text>
<Button primary style={{ marginTop: 10 }}>
<Text>点击我</Text>
</Button>
</Content>
</Container>

2.1.3 React Native Paper

1
npm install react-native-paper
1
2
3
4
5
6
7
8
9
10
11
12
import { Provider as PaperProvider, Button, Text, Divider } from 'react-native-paper';

// 使用
<PaperProvider>
<View style={{ padding: 20 }}>
<Text variant="headlineLarge">React Native Paper</Text>
<Divider style={{ marginVertical: 10 }} />
<Button mode="contained" onPress={() => console.log('Pressed')}>
点击我
</Button>
</View>
</PaperProvider>

2.2 主题管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// theme.js
const theme = {
colors: {
primary: '#007AFF',
secondary: '#5856D6',
background: '#F2F2F7',
surface: '#FFFFFF',
text: '#000000',
error: '#FF3B30',
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
fontSizes: {
xs: 12,
sm: 14,
md: 16,
lg: 18,
xl: 24,
xxl: 32,
},
borderRadius: {
sm: 4,
md: 8,
lg: 16,
xl: 24,
},
};

export default theme;

// 使用
import theme from './theme';

const styles = StyleSheet.create({
container: {
backgroundColor: theme.colors.background,
padding: theme.spacing.md,
borderRadius: theme.borderRadius.md,
},
title: {
fontSize: theme.fontSizes.lg,
color: theme.colors.text,
marginBottom: theme.spacing.sm,
},
});

3. 响应式设计

3.1 使用Dimensions API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Dimensions } from 'react-native';

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

const styles = StyleSheet.create({
container: {
width: width * 0.8,
height: height * 0.6,
},
// 根据屏幕宽度调整字体大小
title: {
fontSize: width > 375 ? 20 : 18,
},
});

3.2 使用Platform API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
container: {
padding: Platform.OS === 'ios' ? 20 : 16,
},
// iOS和Android不同的样式
button: {
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: {
elevation: 4,
},
}),
},
});

4. 实用样式技巧

4.1 阴影效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// iOS
const shadowStyle = {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
};

// Android
const elevationStyle = {
elevation: 4,
};

// 跨平台阴影
const crossPlatformShadow = {
...Platform.select({
ios: shadowStyle,
android: elevationStyle,
}),
};

4.2 渐变背景

1
npm install react-native-linear-gradient
1
2
3
4
5
6
7
8
9
10
import LinearGradient from 'react-native-linear-gradient';

<LinearGradient
colors={['#4c669f', '#3b5998', '#192f6a']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.gradient}
>
<Text style={styles.text}>渐变背景</Text>
</LinearGradient>

4.3 动画样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { Animated } from 'react-native';

// 创建动画值
const opacity = new Animated.Value(0);
const scale = new Animated.Value(0.8);

// 启动动画
Animated.parallel([
Animated.timing(opacity, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}),
Animated.spring(scale, {
toValue: 1,
tension: 50,
friction: 8,
useNativeDriver: true,
}),
]).start();

// 使用动画值
<Animated.View
style={{
opacity,
transform: [{ scale }],
}}
>
<Text>动画效果</Text>
</Animated.View>

5. 最佳实践

5.1 样式组织

  1. 分离样式文件:将样式与组件逻辑分离
  2. 使用常量:定义颜色、间距等常量
  3. 组件化样式:创建可重用的样式组件
  4. 避免内联样式:使用StyleSheet.create提高性能
  5. 使用命名规范:采用一致的命名规则

5.2 性能优化

  1. 使用StyleSheet.create:缓存样式对象
  2. 避免频繁样式计算:提前计算样式值
  3. 使用原生驱动动画:提升动画性能
  4. 减少重绘:合理使用shouldComponentUpdate或React.memo
  5. 优化布局:避免嵌套过深的视图层次

5.3 可访问性

  1. 设置accessibilityLabel:为组件添加可访问性标签
  2. 使用语义化组件:使用合适的组件类型
  3. 确保足够的对比度:文本与背景的对比度
  4. 支持动态字体大小:响应系统字体设置
  5. 测试可访问性:使用辅助功能测试工具

6. 实际应用示例

6.1 登录屏幕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import React from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet, Image } from 'react-native';

const LoginScreen = () => {
return (
<View style={styles.container}>
<Image
source={require('../assets/logo.png')}
style={styles.logo}
resizeMode="contain"
/>
<Text style={styles.title}>欢迎回来</Text>
<Text style={styles.subtitle}>请登录您的账号</Text>

<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>邮箱</Text>
<TextInput
style={styles.input}
placeholder="请输入邮箱"
keyboardType="email-address"
autoCapitalize="none"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>密码</Text>
<TextInput
style={styles.input}
placeholder="请输入密码"
secureTextEntry
/>
</View>

<TouchableOpacity style={styles.forgotPassword}>
<Text style={styles.forgotPasswordText}>忘记密码?</Text>
</TouchableOpacity>

<TouchableOpacity style={styles.loginButton}>
<Text style={styles.loginButtonText}>登录</Text>
</TouchableOpacity>

<View style={styles.registerContainer}>
<Text style={styles.registerText}>还没有账号?</Text>
<TouchableOpacity>
<Text style={styles.registerLink}>立即注册</Text>
</TouchableOpacity>
</View>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
padding: 24,
justifyContent: 'center',
},
logo: {
width: 120,
height: 120,
alignSelf: 'center',
marginBottom: 32,
},
title: {
fontSize: 28,
fontWeight: 'bold',
color: '#333333',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#666666',
marginBottom: 32,
},
inputContainer: {
marginBottom: 20,
},
inputLabel: {
fontSize: 14,
color: '#333333',
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: '#E0E0E0',
borderRadius: 8,
padding: 12,
fontSize: 16,
color: '#333333',
},
forgotPassword: {
alignSelf: 'flex-end',
marginBottom: 32,
},
forgotPasswordText: {
fontSize: 14,
color: '#007AFF',
},
loginButton: {
backgroundColor: '#007AFF',
borderRadius: 8,
padding: 16,
alignItems: 'center',
marginBottom: 24,
},
loginButtonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
},
registerContainer: {
flexDirection: 'row',
justifyContent: 'center',
},
registerText: {
fontSize: 14,
color: '#666666',
},
registerLink: {
fontSize: 14,
color: '#007AFF',
marginLeft: 4,
},
});

export default LoginScreen;

6.2 卡片组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import React from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity, Platform } from 'react-native';

const Card = ({ title, description, image, onPress }) => {
return (
<TouchableOpacity style={styles.card} onPress={onPress}>
<Image source={image} style={styles.image} resizeMode="cover" />
<View style={styles.content}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.description} numberOfLines={2}>{description}</Text>
</View>
</TouchableOpacity>
);
};

const styles = StyleSheet.create({
card: {
backgroundColor: '#FFFFFF',
borderRadius: 12,
marginBottom: 16,
overflow: 'hidden',
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: {
elevation: 3,
},
}),
},
image: {
width: '100%',
height: 180,
},
content: {
padding: 16,
},
title: {
fontSize: 18,
fontWeight: '600',
color: '#333333',
marginBottom: 8,
},
description: {
fontSize: 14,
color: '#666666',
lineHeight: 20,
},
});

export default Card;

7. 参考资料


参考