React Native沙盒环境基础组件
# 概念
# 组件
// 容器组件,相当于 <div></div>,
// 但是对于内容超出容器高度的情况是不能滚动的
// 默认使用 flexbox 布局
<View />
// 可滚动的容器组件,
// 一次会渲染所有节点,适合数据不多的滚动
<ScrollView />
// 可滚动的容器组件,
// 懒加载结点,适合长列表
<FlatList />
// 文本组件,负责展示文本。
// 注意在 RN 中,文本必须被 Text 组件包裹
<Text>文本</Text>
// 按钮,按钮的文本通过 title 属性赋值。
// 此外,RN 中点击事件是 onPress 而不是 onClick。
<Button
onPress={onPressHandler}
title="按钮"
/>
// 输入框
<TextInput
onChangeText={onChangeText}
value={text}
/>
// 图片,本地图片使用 require 引入,网络图片通过 uri 属性引入
<Image source={require('./img/check.png')} />
<Image
source={{uri: 'https://reactjs.org/logo-og.png'}}
style={{width: 400, height: 400}
/>
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
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
笔记
RN 中并不是每个组件都有点击事件,像 Image 和 View 都是没有 onPress 事件的,为了帮这些组件绑定点击事件,需要在包裹在特定的组件中来实现
# 特定组件
// 1.透明效果
<TouchableOpacity onPress={onPress}>
<Text>文本</Text>
</TouchableOpacity>
// 2.高亮
<TouchableHighlight onPress={onPress}>
<View>
<Text>文本</Text>
</View>
</TouchableHighlight>
// 3.原生的反馈
<TouchableNativeFeedback
onPress={() => {
setRippleColor(randomHexColor());
setRippleOverflow(!rippleOverflow);
}}
background={TouchableNativeFeedback.Ripple(rippleColor, rippleOverflow)}
>
<View>
<Text>文本</Text>
</View>
</TouchableNativeFeedback>
// 4.无反馈
<TouchableWithoutFeedback onPress={() => alert('Pressed!')}>
<MyComponent />
</TouchableWithoutFeedback>;
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
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
# 样式
// 官方的例子
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const App = () => (
<View style={styles.container}>
<Text style={styles.title}>React Native</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: "#eaeaea"
},
title: {
marginTop: 16,
paddingVertical: 8,
borderWidth: 4,
borderColor: "#20232a",
borderRadius: 6,
backgroundColor: "#61dafb",
color: "#20232a",
textAlign: "center",
fontSize: 30,
fontWeight: "bold"
}
});
export default App;
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
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
# 安卓与 iOS 系统的样式差异
安卓与 iOS 系统的样式差异,需要开发人员根据各个系统去适配,比如同样给容器增加阴影。在安卓中直接使用 View Style Props 中的 elevation 来实现,而 iOS 中需要使用 ShadowStyleIOS 来实现。
const styles = StyleSheet.create({
card: {
padding: 20,
backgroundColor: "white",
borderRadius: 10,
// 安卓实现 View 阴影样式
elevation: 8,
// iOS 实现 View 阴影样式
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.26,
},
}); 作者:无限咪咪 https://www.bilibili.com/read/cv18201766/ 出处:bilibili
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 键盘
如何关闭键盘?点击输入框可以弹出键盘,但是如果我们不提交的话,是无法手动关闭键盘的。如果需要关闭键盘,可以通过全局的 Touchable 组件,配合 KeyBoard API 来实现。
<TouchableWithoutFeedback onPress={Keyboard.dismiss()}>
// ...
</TouchableWithoutFeedback>
1
2
3
2
3
# 自定义字体
安装expo-font 库
expo install expo-font
1在程序入口加载字体资源
import { useFonts } from 'expo-font'; // ... const [loaded] = useFonts({ Montserrat: require('./assets/fonts/Montserrat.ttf'), }); // ...
1
2
3
4
5
6
7
# 图标
使用 Icons 同样需要 expo 的介入,@expo/vector-icons 这个库默认已经在初始化 expo 项目时安装好了,使用方法如下
import Ionicons from '@expo/vector-icons/Ionicons';
export default function App() {
return (
<View style={styles.container}>
// name 的取值可以去 https://icons.expo.fyi/ 这个网站查
<Ionicons name="md-checkmark-circle" size={32} color="green" />
</View>
);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 整合第三方 UI 库
expo 官网指南中提到的几个 UI 库 https://docs.expo.dev/guides/userinterface/
# 警告
Alert.alert(
"Alert 标题",
"Alert 内容信息",
// 按钮组,可以定义按钮样式与回调函数
[
{
text: "取消",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "确认", onPress: () => console.log("OK Pressed") }
]
);
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 屏幕
import {
useWindowDimensions,
Dimensions,
SafeAreaView
} from 'react-native';
// 1
// 获取设备像素信息
// 这里的 height width 是响应式的,会随着屏幕尺寸改变而改变
const { height, width } = useWindowDimensions();
// 监听屏幕方向变化
Dimensions.addEventListener("change", ({ window, screen }) => {})
// SafeAreaView 组件提供通用的安全显示区域,防止刘海屏遮挡屏幕内容
const App = () => {
return (
<SafeAreaView style={styles.container}>
<Text>内容</Text>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
});
// KeyboardAvoidingView
// 可以防止软键盘遮挡输入区
const KeyboardAvoidingComponent = () => {
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View>
<Text>Header</Text>
<TextInput placeholder="Username" />
<View>
<Button title="Submit" onPress={() => null} />
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
};
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
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
# 检测平台
通过 Platform API 可以获取设备的平台信息
import { Platform, StyleSheet } from 'react-native';
// 获取当前操作系统名称
console.log(Platform.OS); // enum('android', 'ios')
// 使用 .select() 方法来获取类似 switch 的功能
const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
android: {
backgroundColor: 'green'
},
ios: {
backgroundColor: 'red'
},
default: {
// other platforms, web for example
backgroundColor: 'blue'
}
})
}
});
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 旋转
expo 初始化的项目根目录,会有 app.json 文件,其中的 expo.orientation 属性可以锁定 App 的旋转
{
"expo": {
// ...
// 一共有三种取值 default, portrait, landscape
// 默认为 default, 不限制转向
// portrait 时,限制程序为纵向
// landscape 时,限制程序为横向
"orientation": "portrait",
// ...
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
如果需要运行时更改屏幕的方向,可以使用 expo-screen-orientation
这个库来实现。
上次更新: 2024/08/14, 04:14:33