经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » React » 查看文章
React Native实现Toast轻提示和loading - Lanny-Chung
来源:cnblogs  作者:Lanny-Chung  时间:2023/9/1 8:48:06  对本文有异议

React Native 封装Toast

前言

使用react native的小伙伴都知道,官方并未提供轻提示组件,只提供了ToastAndroid API,顾名思义,只能再安卓环境下使用,对于ios就爱莫能助,故此,只能通过官方的核心组件,自行封装,实现Toast功能

实现

创建文件

首先我们需要创建一个Toast组件,引入对应需要的依赖,icon等等
声明数据类型,通用方法

  1. import React, {Component} from 'react';
  2. import {View, Text, StyleSheet, Animated, Easing} from 'react-native';
  3. import icon_success from '../assets/images/icon-success.png';
  4. import icon_error from '../assets/images/icon-error.png';
  5. import icon_loading from '../assets/images/icon-loading.png';
  6. import icon_warning from '../assets/images/icon-warning.png';
  7. type StateType = {
  8. isVisible: boolean;
  9. icon: any;
  10. message: string;
  11. };
  12. type ParamsType = string | {message: string; duration?: number};
  13. function getParams(data: ParamsType): {message: string; duration: number} {
  14. let msg!: string;
  15. let dur!: number;
  16. if (typeof data === 'string') {
  17. msg = data;
  18. dur = 2000;
  19. } else {
  20. msg = data.message;
  21. dur = data.duration != null ? data.duration : 2000;
  22. }
  23. return {
  24. message: msg,
  25. duration: dur,
  26. };
  27. }

实现样式和UI层次渲染

我们需要创建一个class,接收参数,并根据不同的条件渲染:success、error、warning、show、loading等
并抛出自己的实例

  1. class ToastComponent extends Component<{} | Readonly<{}>, StateType> {
  2. timeout!: NodeJS.Timeout;
  3. rotate: Animated.Value = new Animated.Value(0);
  4. constructor(props: {} | Readonly<{}>) {
  5. super(props);
  6. this.state = {
  7. isVisible: false,
  8. icon: null,
  9. message: '',
  10. };
  11. Toast.setToastInstance(this);
  12. }
  13. showToast(icon: any, message: string, duration: number) {
  14. this.setState({
  15. isVisible: true,
  16. icon,
  17. message,
  18. });
  19. if (duration !== 0) {
  20. const timeout = setTimeout(() => {
  21. this.closeToast();
  22. }, duration);
  23. this.timeout = timeout;
  24. }
  25. }
  26. showRotate() {
  27. Animated.loop(
  28. Animated.timing(this.rotate, {
  29. toValue: 360,
  30. duration: 1000,
  31. easing: Easing.linear,
  32. useNativeDriver: true,
  33. }),
  34. ).start();
  35. }
  36. closeToast() {
  37. this.setState({
  38. isVisible: false,
  39. icon: null,
  40. message: '',
  41. });
  42. if (this.timeout) {
  43. clearTimeout(this.timeout);
  44. }
  45. }
  46. render() {
  47. const {isVisible, icon, message} = this.state;
  48. return isVisible ? (
  49. <View style={style.root}>
  50. <View style={[style.main, icon === null ? null : style.mainShowStyle]}>
  51. {icon && (
  52. <Animated.Image
  53. style={[
  54. style.icon,
  55. {
  56. transform: [
  57. {
  58. rotate: this.rotate.interpolate({
  59. inputRange: [0, 360],
  60. outputRange: ['0deg', '360deg'],
  61. }),
  62. },
  63. ],
  64. },
  65. ]}
  66. source={icon}
  67. />
  68. )}
  69. <Text style={style.tip}>{message}</Text>
  70. </View>
  71. </View>
  72. ) : null;
  73. }
  74. }
  75. const style = StyleSheet.create({
  76. root: {
  77. height: '100%',
  78. backgroundColor: 'transparent',
  79. position: 'absolute',
  80. top: 0,
  81. left: 0,
  82. right: 0,
  83. bottom: 0,
  84. zIndex: 99999,
  85. alignItems: 'center',
  86. justifyContent: 'center',
  87. },
  88. main: {
  89. maxWidth: 200,
  90. maxHeight: 200,
  91. backgroundColor: '#00000099',
  92. borderRadius: 8,
  93. alignItems: 'center',
  94. justifyContent: 'center',
  95. padding: 20,
  96. },
  97. mainShowStyle: {
  98. minWidth: 140,
  99. minHeight: 140,
  100. },
  101. icon: {
  102. width: 36,
  103. height: 36,
  104. resizeMode: 'cover',
  105. marginBottom: 20,
  106. },
  107. tip: {
  108. fontSize: 14,
  109. color: '#fff',
  110. fontWeight: 'bold',
  111. textAlign: 'center',
  112. },
  113. });

抛出对外调用的方法

此时我们需要再声明一个class,对外抛出方法以供调用
最后导出即可

  1. class Toast extends Component<{} | Readonly<{}>, {} | Readonly<{}>> {
  2. static toastInstance: ToastComponent;
  3. static show(data: ParamsType) {
  4. const {message, duration} = getParams(data);
  5. this.toastInstance.showToast(null, message, duration);
  6. }
  7. static loading(data: ParamsType) {
  8. const {message, duration} = getParams(data);
  9. this.toastInstance.showToast(icon_loading, message, duration);
  10. this.toastInstance.showRotate();
  11. }
  12. static success(data: ParamsType) {
  13. const {message, duration} = getParams(data);
  14. this.toastInstance.showToast(icon_success, message, duration);
  15. }
  16. static error(data: ParamsType) {
  17. const {message, duration} = getParams(data);
  18. this.toastInstance.showToast(icon_error, message, duration);
  19. }
  20. static warning(data: ParamsType) {
  21. const {message, duration} = getParams(data);
  22. this.toastInstance.showToast(icon_warning, message, duration);
  23. }
  24. static clear() {
  25. if (this.toastInstance) {
  26. this.toastInstance.closeToast();
  27. }
  28. }
  29. static setToastInstance(toastInstance: ToastComponent) {
  30. this.toastInstance = toastInstance;
  31. }
  32. render() {
  33. return null;
  34. }
  35. };
  36. export {Toast, ToastComponent};

组件挂载

我们需要将UI层组件在入口TSX文件进行挂载,不然Toast无法渲染

  1. /* APP.tsx */
  2. import React from 'react';
  3. import {StatusBar} from 'react-native';
  4. import {SafeAreaProvider} from 'react-native-safe-area-context';
  5. import {ToastComponent} from './src/components/Toast';
  6. const Stack = createStackNavigator();
  7. function App(): JSX.Element {
  8. return (
  9. <SafeAreaProvider>
  10. <StatusBar barStyle="dark-content" backgroundColor="#EAF7FF" />
  11. <ToastComponent />
  12. </SafeAreaProvider>
  13. );
  14. }
  15. export default App;

API调用

挂载完成,接下来,在我们需要用到的地方,调用即可

  1. import {Toast} from '../../components/Toast';
  2. //
  3. Toast.success('登录成功');
  4. Toast.error('密码错误');
  5. Toast.warning('我是警告');
  6. Toast.loading('加载中,请稍后');
  7. Toast.loading({message: "我是不关闭的Toast", duration: 0})
  8. Toast.success({message: "我是2秒后关闭的Toast", duration: 2000});
  9. Toast.clear(); // 手动关闭

原文链接:https://www.cnblogs.com/LannyChung/p/17670013.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号