一 组件简介
1.1 简介
RN中的核心组件,是对原生组件的封装
- 原生组件:Android或ios内的组件
- 核心组件:RN中常用的,来自react-native的组件
原生组件
在 Android 开发中是使用 Kotlin 或 Java 来编写视图;在 iOS 开发中是使用 Swift 或 Objective-C 来编写视图。在 React Native 中,则使用 React 组件通过 JavaScript 来调用这些视图。在运行时,React Native 为这些组件创建相应的 Android 和 iOS 视图。由于 React Native 组件就是对原生视图的封装,因此使用 React Native 编写的应用外观、感觉和性能与其他任何原生应用一样。我们将这些平台支持的组件称为原生组件。
核心组件
官网的核心主键,React Native 具有许多核心组件,从表单控件到活动指示器,应有尽有。将主要使用以下核心组件:
这是参考的核心组件有:
官网的案例
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import { Text, StyleSheet, View , Image, ScrollView, TextInput} from 'react-native';
export default class CoreComponent extends Component {
render() {
return (
<ScrollView>
<Text>Some text</Text>
<View>
<Text>Some more text</Text>
<Image
source={{
uri: 'https://reactnative.dev/docs/assets/p_cat2.png',
}}
// eslint-disable-next-line react-native/no-inline-styles
style={{ width: 200, height: 200 }}
/>
</View>
<TextInput
// eslint-disable-next-line react-native/no-inline-styles
style={{
height: 40,
borderColor: 'gray',
borderWidth: 1,
}}
defaultValue="You can type in me"
/>
</ScrollView>
);
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const styles = StyleSheet.create({});
效果:
Alert和Button
Button是一个简单的跨平台的按钮组件。下面是一个最简示例:
AlertAndButton.tsx
/* eslint-disable prettier/prettier */
/* eslint-disable quotes */
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Alert, StyleSheet, View,Button} from 'react-native';
export default class AlertAndButton extends Component {
// onPress是处理触摸事件
createTwoButton = ()=>{
Alert.alert(
"警告标题",
"警告内容",
[
{
text:"取消",
onPress:()=>console.log("Cancel"),
style:'cancel',
},
{
text:"确认",
onPress:()=>console.log("OK"),
style:'default',
},
]
);
};
createThreeButton = ()=>{
Alert.alert(
"更新提示",
"发现新版本,是否现在更新",
[
{
text:"取消",
onPress:()=>console.log("Cancel"),
style:'cancel',
},
{
text:"确认",
onPress:()=>console.log("OK"),
style:'default',
},
{
text:"稍后再试",
onPress:()=>console.log("稍后提醒我"),
},
]
);
};
render() {
return (
<View style={[styles.container]}>
<Button
onPress={() => {
Alert.alert('你点击了按钮!');
}}
title="点我!"
/>
<Button
onPress={this.createTwoButton}
title="两个按钮"
color={'green'}
/>
<Button
onPress={this.createThreeButton}
title="三个按钮"
color={'pink'}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
justifyContent: 'space-around',
alignItems: 'center',
},
});
上面这段代码会在 iOS 上渲染一个蓝色的标签状按钮,在 Android 上则会渲染一个蓝色圆角矩形带白字的按钮。点击这个按钮会调用"onPress"函数,具体作用就是显示一个 alert 弹出框。你还可以指定"color"属性来修改按钮的颜色。
运行效果:点击按钮弹出提示框
再试试下面这个使用Button的例子吧。你可以点击"Tap to Play"来预览真实效果
import React, { Component } from 'react';
import { Alert, Button, StyleSheet, View } from 'react-native';
export default class ButtonBasics extends Component {
_onPressButton() {
Alert.alert('You tapped the button!')
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
color="#841584"
/>
</View>
<View style={styles.alternativeLayoutButtonContainer}>
<Button
onPress={this._onPressButton}
title="This looks great!"
/>
<Button
onPress={this._onPressButton}
title="OK!"
color="#841584"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer: {
margin: 20
},
alternativeLayoutButtonContainer: {
margin: 20,
flexDirection: 'row',
justifyContent: 'space-between'
}
})
运行效果:
Switch和StatuBas
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import { StatusBar, StyleSheet, Switch, View } from 'react-native';
export default class SwitchAndStatuBar extends Component<any,any> {
constructor(props:any){
super(props);
this.state = {
hideStatusBar:false,
};
}
render() {
return (
<View style={[styles.container]}>
<StatusBar
hidden={this.state.hideStatusBar} //是否显示顶部
backgroundColor="blue" //仅在Android应用下有效
barStyle={'dark-content'}<br> //用于设置状态栏文字的颜色,其值是枚举类型enum(‘default’, ‘light-content’, ‘dark-content’):<br> //default:黑色文字(默认)<br> //light-content:白色文字<br> //dark-content: 暗色文字
/><br> //开关组件
<Switch
trackColor={{false:'red',true:'green'}}
thumbColor={this.state.hideStatusBar ? 'red' : 'white'}
value={this.state.hideStatusBar}<br> //选中事件
onValueChange={()=>{this.setState({hideStatusBar:!this.state.hideStatusBar});}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center',
},
});
运行效果:
ActivityIndicator
ActivityIndicator的效果类似我们平时看到了loading,在android中ActivityIndicator是progressBar 的Indeterminate(false)模式,说白了就是一个半圆转啊转。
具体属性:
1、ViewPropTypes props… :包含View控件的所有属性,具体咱们看View的属性解释。
2、animating:是否显示,默认true(显示)
3、color: 指示器的颜色, ios默认为gray(#999999),android 默认使用progressBar的系统样式,取决于你设置的style。
4、size: 表示大小,可以设置的值有:
‘small’: 宽高各20
‘large’: 宽高各36
5、hidesWhenStopped:此属性只在ios生效,当停止动画的时候,是否隐藏。默认为true。
ActivityIndicatorDemo.tsx
import React, {Component} from 'react';
import {
StyleSheet,
View,
Text,
ActivityIndicator,
} from 'react-native';
export default class ActivityIndicatorDemo extends Component {
render() {
return (
<View style={{flex:1}}>
<View style={{flexDirection:'row'}}>
<Text>全部默认:</Text>
<ActivityIndicator />
</View>
<View style={{flexDirection:'row'}}>
<Text>添加背景色:</Text>
<ActivityIndicator style={{backgroundColor:'blue'}}/>
</View>
<View style={{flexDirection:'row'}}>
<Text>animating=false (隐藏):</Text>
<ActivityIndicator animating={false}/>
</View>
<View style={{flexDirection:'row'}}>
<Text>设置color:</Text>
<ActivityIndicator color='red'/>
</View>
<View style={{flexDirection:'row'}}>
<Text>size small:</Text>
<ActivityIndicator size="small"/>
<Text>size large:</Text>
<ActivityIndicator size="large"/>
</View>
<View style={{flexDirection:'row'}}>
<Text>view props属性设置:</Text>
<ActivityIndicator style={{height:100,width:80,backgroundColor:'black'}} />
</View>
</View>
);
}
}
运行效果:
Image图片加载
1、source图片路径
ImageDemo.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {View, Image, StyleSheet, Dimensions} from 'react-native';
export default class ImageDemo extends Component {
render() {
return (
<View style={[styles.container]}>
<Image style={[styles.items]} source={require('./images/logo.jpg')} />
<Image
style={styles.tinyLogo}
source={{uri: 'https://reactnative.dev/img/tiny_logo.png'}}
/>
<Image
style={styles.logo}
source={{
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
items:{
height:200,
width:Dimensions.get('window').width,
},
tinyLogo: {
width: 50,
height: 50,
},
logo: {
width: 66,
height: 58,
},
});
运行效果:
TextInput
TextInputDemo.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {
StyleSheet,
View,
TextInput,
Dimensions,
Button,
Alert,
} from 'react-native';
export default class TextInputDemo extends Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
username: '',
password: '',
};
}
doLogin = () => {
Alert.alert(this.state.username);
};
render() {
return (
<View style={[styles.containers]}>
<TextInput
value={this.state.username}
style={[styles.input]}
placeholder="请输入用户名"
onChangeText={_val => {
this.setState({username: _val});
}}
/>
<TextInput
style={[styles.input]}
placeholder="请输入密码"
value={this.state.password}
//保护密码
secureTextEntry={true}
onChangeText={_val => {
this.setState({password: _val});
}}
/>
<TextInput
style={[styles.input]}
placeholder="请输入手机号"
//数字键盘
keyboardType="number-pad"
/>
<TextInput
style={[styles.input]}
placeholder="文本域"
multiline={true}
numberOfLines={5}
textAlignVertical="top"
/>
<View>
<Button title="登录" onPress={this.doLogin} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
containers: {
flex: 1,
justifyContent: 'center',
},
input: {
width: Dimensions.get('window').width - 20,
margin: 10,
borderWidth: 1,
borderColor: 'red',
paddingHorizontal: 5,
},
});
运行效果:
Touchable组件
- TouchableHighlight:触碰后,高亮显示
- TouchableOpacity:触碰后,透明度降低(模糊显示)
- TouchaleWithoutFeedback:触碰后,无影响
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import { Text, StyleSheet, View, TouchableHighlight, Alert, TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
export default class TouchaleDemo extends Component {
render() {
return (
<View style={[styles.container]}>
<TouchableHighlight onPress={()=>{
Alert.alert('触碰高亮显示');
}} >
<View>
<Text style={[styles.item]}> 触碰高亮 </Text>
</View>
</TouchableHighlight>
<TouchableOpacity onPress={()=>{
Alert.alert('触碰透明的变化');
}}>
<View>
<Text style={[styles.item]}> 触碰透明的变化 </Text>
</View>
</TouchableOpacity>
<TouchableWithoutFeedback onPress={()=>{
Alert.alert('触碰无效');
}}>
<View>
<Text style={[styles.item]}> 触碰无效 </Text>
</View>
</TouchableWithoutFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center',
},
item:{
marginBottom:20,
padding:10,
borderWidth:1,
borderColor:'red',
},
});
运行效果:
ScrollView和SafeAreaView
ScrollView是一个通用的可滚动的容器,你可以在其中放入多个组件和视图,而且这些组件并不需要是同类型的。ScrollView不仅可以垂直滚动(默认),还能水平滚动(通过horizontal属性来设置)。
ScrollView常用属性:
horizontal(布尔值):当此属性为true的时候,所有的的子视图会在水平方向上排成一行,而不是默认的在垂直方向上排成一列。默认值为false。
showsHorizontalScrollIndicator(布尔值):当此属性为true的时候,显示一个水平方向的滚动条。
showsVerticalScrollIndicator(布尔值):与showsHorizontalScrollIndicator相对,当此属性为true的时候,显示一个垂直方向的滚动条。
OnMomentumScrollEnd(function) :当一帧滚动完毕的时候调用,e.nativeEvent.contentOffset,可以用来获取偏移量。
onScrollBeginDrag(function) :当开始手动拖拽的时候调用。
onScrollEndDrag(function) :当结束手动拖拽的时候调用。
onScroll(function) :在滚动的过程中,每帧最多调用一次此回调函数。调用的频率可以用scrollEventThrottle属性来控制。
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {
Text,
StyleSheet,
SafeAreaView,
ScrollView,
StatusBar,
View,
Platform,
} from 'react-native';
export default class ScrollViewDemo extends Component {
render() {
return (
<SafeAreaView>
<ScrollView horizontal={true}>
<Text style={[styles.nav]}>新闻</Text>
<Text style={[styles.nav]}>娱乐</Text>
<Text style={[styles.nav]}>体育</Text>
<Text style={[styles.nav]}>财经</Text>
<Text style={[styles.nav]}>军事</Text>
<Text style={[styles.nav]}>新闻</Text>
<Text style={[styles.nav]}>时尚</Text>
<Text style={[styles.nav]}>科技</Text>
</ScrollView>
<ScrollView
style={styles.scrollView}
//隐藏滚动条
showsVerticalScrollIndicator={false}>
<Text style={styles.text}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</Text>
<View style={{height:Platform.OS === 'ios' ? 0 : 100}} />
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
},
scrollView: {
backgroundColor: 'pink',
marginHorizontal: 20,
},
text: {
fontSize: 42,
},
nav: {
margin: 10,
height: 50,
fontSize: 30,
},
});
运行效果:有滚动效果
SectionList
用于呈现分区列表的高性能界面,支持最方便的功能:
- 完全跨平台。
- 可配置的可见度回传。
- 列表标题支持。
- 列表页脚支持。
- 项目分隔符支持。
- 节标题支持。
- 节分隔符支持。
- 异构数据和项目呈现支持。
- 拉动以刷新。
- 滚动加载。
如果您不需要部分支持并且想要更简单的界面,请使用
官网案例:
SectionListDemo.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import { StyleSheet,
Text,
View,
SafeAreaView,
SectionList,
StatusBar} from 'react-native';
export default class SectionListDemo extends Component {
DATA = [
{
title: 'Main dishes',
data: ['Pizza', 'Burger', 'Risotto'],
},
{
title: 'Sides',
data: ['French Fries', 'Onion Rings', 'Fried Shrimps'],
},
{
title: 'Drinks',
data: ['Water', 'Coke', 'Beer'],
},
{
title: 'Desserts',
data: ['Cheese Cake', 'Ice Cream'],
},
];
render() {
return (
<SafeAreaView style={styles.container}>
<SectionList
sections={this.DATA}
keyExtractor={(item, index) => item + index}
renderItem={({item}) => (
<View style={styles.item}>
<Text style={styles.title}>{item}</Text>
</View>
)}
renderSectionHeader={({section: {title}}) => (
<Text style={styles.header}>{title}</Text>
)}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
marginHorizontal: 16,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
},
header: {
fontSize: 32,
backgroundColor: '#fff',
},
title: {
fontSize: 24,
},
});
运行效果:
Animated
Animated库旨在使动画变得流畅,强大并易于构建和维护。Animated侧重于输入和输出之间的声明性关系,以及两者之间的可配置变换,此外还提供了简单的 start/stop方法来控制基于时间的动画执行。
创建动画最基本的工作流程是先创建一个 Animated.Value ,将它连接到动画组件的一个或多个样式属性,然后使用Animated.timing()通过动画效果展示数据的变化:
Animated库旨在使动画变得流畅,强大并易于构建和维护。Animated侧重于输入和输出之间的声明性关系,以及两者之间的可配置变换,此外还提供了简单的 start/stop方法来控制基于时间的动画执行。
创建动画最基本的工作流程是先创建一个 Animated.Value ,将它连接到动画组件的一个或多个样式属性,然后使用Animated.timing()通过动画效果展示数据的变化:
AnimatedDemo.tsx
复制代码
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View,Animated,Button} from 'react-native';
export default class AnimatedDemo extends Component {
// fadeAnim will be used as the value for opacity. Initial Value: 0
state = {
fadeAnim: new Animated.Value(0),
};
fadeIn = () => {
// Will change fadeAnim value to 1 in 5 seconds
Animated.timing(this.state.fadeAnim, {
//目标值
toValue: 1,
//动画执行的时间
duration: 5000,
//启动原生方式,渲染动画(执行效率更高)
useNativeDriver: true,
}).start();
};
fadeOut = () => {
// Will change fadeAnim value to 0 in 5 seconds
Animated.timing(this.state.fadeAnim, {
toValue: 0,
duration: 5000,
useNativeDriver: true,
}).start();
};
render() {
return (
<View style={styles.container}>
<Animated.View
style={[
styles.fadingContainer,
{
opacity: this.state.fadeAnim, // Bind opacity to animated value
},
]}
>
<Text style={styles.fadingText}>Fading View!</Text>
</Animated.View>
<View style={styles.buttonRow}>
{/* 淡入 */}
<Button title="Fade In" onPress={this.fadeIn} />
{/* 淡出 */}
<Button title="Fade Out" onPress={this.fadeOut} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
fadingContainer: {
paddingVertical: 8,
paddingHorizontal: 16,
backgroundColor: 'powderblue',
},
fadingText: {
fontSize: 28,
textAlign: 'center',
margin: 10,
},
buttonRow: {
flexDirection: 'row',
marginVertical: 16,
},
});
运行效果:点击FADEIN 有淡出效果,FADEOUT淡出效果
二 第三方组件
通过命令安装第三的组件
2.1 WebView
引入的命令:
yarn add react-native-webview
配置:
https://github.com/react-native-webview/react-native-webview/blob/master/docs/Getting-Started.md
示例:MyWeb.js
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {WebView} from 'react-native-webview';
export default class MyWeb extends Component {
render() {
return (
//链接到百度的网址
<WebView source={{uri: 'https://baidu.com'}} style={{marginTop: 20}} />
);
}
}
复制代码
运行效果:
回到顶部
6.2、Picker(下拉框)
引入的命令:
yarn add @react-native-picker/picker
配置:
https://github.com/react-native-picker/picker
示例:PickerDemo.js
复制代码
/* eslint-disable prettier/prettier */
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import {Picker} from '@react-native-picker/picker';
export default function PickerDemo(){
const [selectedLanguage, setSelectedLanguage] = useState();
return (
<View>
<Picker
//下拉框样式
mode={'dropdown'}
selectedValue={selectedLanguage}
onValueChange={(itemValue, itemIndex) =>
setSelectedLanguage(itemValue)
}>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
</Picker>
</View>
);
}
运行效果:
6.2、Picker(下拉框
引入的命令:
yarn add @react-native-picker/picker
配置:
https://github.com/react-native-picker/picker
示例:PickerDemo.js
/* eslint-disable prettier/prettier */
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import {Picker} from '@react-native-picker/picker';
export default function PickerDemo(){
const [selectedLanguage, setSelectedLanguage] = useState();
return (
<View>
<Picker
//下拉框样式
mode={'dropdown'}
selectedValue={selectedLanguage}
onValueChange={(itemValue, itemIndex) =>
setSelectedLanguage(itemValue)
}>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
</Picker>
</View>
);
}
6.3、Swiper(轮播效果)
引入的命令:
npm i --save react-native-swiper@next
配置:
https://github.com/leecade/react-native-swiper
示例:SwiperDemo.js
/* eslint-disable prettier/prettier */
import React from 'react';
import {Text, View} from 'react-native';
import Swiper from 'react-native-swiper';
var styles = {
wrapper: {},
slide1: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#9DD6EB',
},
slide2: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#97CAE5',
},
slide3: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#92BBD9',
},
text: {
color: '#fff',
fontSize: 30,
fontWeight: 'bold',
},
};
export default () => (
<Swiper style={styles.wrapper} showsButtons loop={false}>
<View testID="Hello" style={styles.slide1}>
<Text style={styles.text}>Hello Swiper</Text>
</View>
<View testID="Beautiful" style={styles.slide2}>
<Text style={styles.text}>Beautiful</Text>
</View>
<View testID="Simple" style={styles.slide3}>
<Text style={styles.text}>And simple</Text>
</View>
</Swiper>
);
运行效果:
6.4、Async Storage
数据存储是开发APP必不可少的一部分,比如页面缓存,从网络上获取数据的本地持久化等,那么在RN中如何进行数据存储呢?RN官方推荐我们在RN中使用AsyncStorage进行数据存储。
- 什么是AsyncStorage?
2.1 特点
简单的,异步的,持久化的key-value存储系统
AsyncStorage也是React Native官方推荐的数据存储方式,旨在代替LocalStorage
2.2 AsyncStorage在ios中存储的两种情况
如果存储的内容较小,那么AsyncStorage会将存储的内容放在一个序列化的字典中
如果存储的内容较大,那么AsyncStorage会将存储的内容放在一个单独的文件中
2.3 AsyncStorage在android中存储也分为两种情况:
AsyncStorage会将数据存储在RocksDB或者SQLite中,具体存在RocksDB中还是SQLite中这取决于设备支持哪一种存储方式。 - 如何使用AsyncStorage?
引入命令:
import AsyncStorage from ‘@react-native-async-storage/async-storage’
官网路径:
https://react-native-async-storage.github.io/async-storage/docs/usage/
示例:AsyncStroage.js
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import { Text, StyleSheet, View, Alert, Button } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default class AsyncStroage extends Component {
storeData (value){
try {
AsyncStorage.setItem('@storage_Key', value);
} catch (e) {
// saving error
console.log(e);
}
console.log(value);
}
getData = async () => {
try {
const value = await AsyncStorage.getItem('@storage_Key');
if (value !== null) {
Alert.alert(value);
}
} catch (e) {
// error reading value
}
};
render() {
return (
<View style={[styles.container]}>
<Button title="存储" onPress={this.storeData.bind(this,'Hello RN')}/>
<Button title="获取" onPress={this.getData}/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center',
},
});
运行效果:
点击按钮实现数据的存储,点击获取可以获取你刚刚存储的数据显示