toast只有在android平臺才可以使用,在ios平臺沒有,而一般用到的時候都希望兩個平臺能一起使用,使用動畫來封裝一個存js的,兩個平臺一起使用。
元件原始碼Toast.tsx
import * as React from 'react';
import {Animated, Dimensions, StyleSheet, Text, TextStyle, View, ViewStyle} from 'react-native';
const {width, height} = Dimensions.get('window');
interface IProps {
textStyle?: TextStyle;
containerStyle?: ViewStyle;
position?: 'top' | 'center' | 'bottom';
opacity?: number;
fadeInDuration?: number;
fadeOutDuration?: number;
defaultCloseDelay?: number;
positionValue?: number;
}
interface IState {
visible: boolean;
text: string;
}
class Toast extends React.Component<IProps, IState> {
visible: boolean;
timer: any;
constructor(props: IProps) {
super(props);
this.visible = false;
}
static DURATION = {
LENGTH_SHORT: 500,
FOREVER: 0
}
public static defaultProps: Partial<IProps> = {
position: 'center',
opacity: 0.8,
fadeInDuration: 500,
fadeOutDuration: 500,
defaultCloseDelay: 250,
positionValue: 20,
textStyle: {
color: 'white'
}
}
state = {
visible: false,
opacityValue: new Animated.Value(this.props.opacity!),
text: ''
}
show(text: string, duration?: number) {
this.setState({
text,
visible: true
});
Animated.timing(this.state.opacityValue, {
toValue: this.props.opacity!,
duration: duration || this.props.fadeInDuration
}).start(() => {
this.visible = true;
if(duration != Toast.DURATION.FOREVER) this.close();
});
}
close(duration: number = this.props.defaultCloseDelay!) {
if (! this.visible && ! this.state.visible) return;
if (this.timer != undefined) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
Animated.timing(this.state.opacityValue, {
toValue: 0.0,
duration: this.props.fadeOutDuration
}).start(() => {
this.setState({
visible: false
});
this.visible = false;
});
}, duration);
}
componentWillUnmount() {
if (this.timer != undefined) {
clearTimeout(this.timer);
}
}
render() {
let pos = 0;
switch (this.props.position) {
case 'top':
pos = this.props.positionValue!;
break;
case 'center':
pos = height / 2;
break;
case 'bottom':
pos = height - this.props.positionValue!;
break;
}
if (this.state.visible) {
return (
<View style={[styles.container, {top: pos}]} pointerEvents="none">
<Animated.View style={[styles.content, { opacity: this.state.opacityValue }, this.props.containerStyle]}>
{React.isValidElement(this.state.text)
? this.state.text
: <Text style={this.props.textStyle}>{this.state.text}</Text>
}
</Animated.View>
</View>
);
}
return null;
}
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
left: 0,
right: 0,
elevation: 999,
alignItems: 'center',
zIndex: 10000,
},
content: {
backgroundColor: 'black',
borderRadius: 5,
padding: 10,
}
});
export default Toast;
複製程式碼
使用
private toast: Toast | null = null;
<Toast ref={ref => this.toast = ref} />
this.toast!.show('HelloWorld!');
// 長時間顯示
this.toast!.show('HelloWorld', 2000);
複製程式碼