React Native实现Toast轻提示和loading效果
前言
使用react native的小伙伴都知道,官方并未提供轻提示组件,只提供了ToastAndroid API,顾名思义,只能再安卓环境下使用,对于ios就爱莫能助,故此,只能通过官方的核心组件,自行封装,实现Toast功能。
实现
创建文件
首先我们需要创建一个Toast组件,引入对应需要的依赖,icon等等
声明数据类型,通用方法
import React, {Component} from 'react'; import {View, Text, StyleSheet, Animated, Easing} from 'react-native'; import icon_success from '../assets/images/icon-success.png'; import icon_error from '../assets/images/icon-error.png'; import icon_loading from '../assets/images/icon-loading.png'; import icon_warning from '../assets/images/icon-warning.png'; type StateType = { isVisible: boolean; icon: any; message: string; }; type ParamsType = string | {message: string; duration?: number}; function getParams(data: ParamsType): {message: string; duration: number} { let msg!: string; let dur!: number; if (typeof data === 'string') { msg = data; dur = 2000; } else { msg = data.message; dur = data.duration != null ? data.duration : 2000; } return { message: msg, duration: dur, }; }
实现样式和UI层次渲染
我们需要创建一个class,接收参数,并根据不同的条件渲染:success、error、warning、show、loading等
并抛出自己的实例
class ToastComponent extends Component<{} | Readonly<{}>, StateType> { timeout!: NodeJS.Timeout; rotate: Animated.Value = new Animated.Value(0); constructor(props: {} | Readonly<{}>) { super(props); this.state = { isVisible: false, icon: null, message: '', }; Toast.setToastInstance(this); } showToast(icon: any, message: string, duration: number) { this.setState({ isVisible: true, icon, message, }); if (duration !== 0) { const timeout = setTimeout(() => { this.closeToast(); }, duration); this.timeout = timeout; } } showRotate() { Animated.loop( Animated.timing(this.rotate, { toValue: 360, duration: 1000, easing: Easing.linear, useNativeDriver: true, }), ).start(); } closeToast() { this.setState({ isVisible: false, icon: null, message: '', }); if (this.timeout) { clearTimeout(this.timeout); } } render() { const {isVisible, icon, message} = this.state; return isVisible ? ( <View style={style.root}> <View style={[style.main, icon === null ? null : style.mainShowStyle]}> {icon && ( <Animated.Image style={[ style.icon, { transform: [ { rotate: this.rotate.interpolate({ inputRange: [0, 360], outputRange: ['0deg', '360deg'], }), }, ], }, ]} source={icon} /> )} <Text style={style.tip}>{message}</Text> </View> </View> ) : null; } } const style = StyleSheet.create({ root: { height: '100%', backgroundColor: 'transparent', position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 99999, alignItems: 'center', justifyContent: 'center', }, main: { maxWidth: 200, maxHeight: 200, backgroundColor: '#00000099', borderRadius: 8, alignItems: 'center', justifyContent: 'center', padding: 20, }, mainShowStyle: { minWidth: 140, minHeight: 140, }, icon: { width: 36, height: 36, resizeMode: 'cover', marginBottom: 20, }, tip: { fontSize: 14, color: '#fff', fontWeight: 'bold', textAlign: 'center', }, });
抛出对外调用的方法
此时我们需要再声明一个class,对外抛出方法以供调用
最后导出即可
class Toast extends Component<{} | Readonly<{}>, {} | Readonly<{}>> { static toastInstance: ToastComponent; static show(data: ParamsType) { const {message, duration} = getParams(data); this.toastInstance.showToast(null, message, duration); } static loading(data: ParamsType) { const {message, duration} = getParams(data); this.toastInstance.showToast(icon_loading, message, duration); this.toastInstance.showRotate(); } static success(data: ParamsType) { const {message, duration} = getParams(data); this.toastInstance.showToast(icon_success, message, duration); } static error(data: ParamsType) { const {message, duration} = getParams(data); this.toastInstance.showToast(icon_error, message, duration); } static warning(data: ParamsType) { const {message, duration} = getParams(data); this.toastInstance.showToast(icon_warning, message, duration); } static clear() { if (this.toastInstance) { this.toastInstance.closeToast(); } } static setToastInstance(toastInstance: ToastComponent) { this.toastInstance = toastInstance; } render() { return null; } }; export {Toast, ToastComponent};
组件挂载
我们需要将UI层组件在入口TSX文件进行挂载,不然Toast无法渲染
/* APP.tsx */ import React from 'react'; import {StatusBar} from 'react-native'; import {SafeAreaProvider} from 'react-native-safe-area-context'; import {ToastComponent} from './src/components/Toast'; const Stack = createStackNavigator(); function App(): JSX.Element { return ( <SafeAreaProvider> <StatusBar barStyle="dark-content" backgroundColor="#EAF7FF" /> <ToastComponent /> </SafeAreaProvider> ); } export default App;
API调用
挂载完成,接下来,在我们需要用到的地方,调用即可
import {Toast} from '../../components/Toast'; // Toast.success('登录成功'); Toast.error('密码错误'); Toast.warning('我是警告'); Toast.loading('加载中,请稍后'); Toast.loading({message: "我是不关闭的Toast", duration: 0}) Toast.success({message: "我是2秒后关闭的Toast", duration: 2000}); Toast.clear(); // 手动关闭
到此这篇关于React Native实现Toast轻提示和loading的文章就介绍到这了,更多相关React Native实现Toast轻提示和loading内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
React报错信息之Expected an assignment or function call and
这篇文章主要介绍了React报错之Expected an assignment or function call and instead saw an expression,下面有两个示例来展示错误是如何产生的,需要的朋友可以参考下2022-08-08useReducer createContext代替Redux原理示例解析
这篇文章主要为大家介绍了useReducer createContext代替Redux原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-11-11
最新评论