React Native 封装Toast
前言
使用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,});
if (this.timeout) {
clearTimeout(this.timeout);
}
}
render() {
const {isVisible,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,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,duration);
}
static loading(data: ParamsType) {
const {message,duration} = getParams(data);
this.toastInstance.showToast(icon_loading,duration);
this.toastInstance.showRotate();
}
static success(data: ParamsType) {
const {message,duration} = getParams(data);
this.toastInstance.showToast(icon_success,duration);
}
static error(data: ParamsType) {
const {message,duration} = getParams(data);
this.toastInstance.showToast(icon_error,duration);
}
static warning(data: ParamsType) {
const {message,duration} = getParams(data);
this.toastInstance.showToast(icon_warning,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(); // 手动关闭
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。