直接上代码
import React, {Component} from 'react';
import {StyleSheet, Dimensions, Animated, Easing} from 'react-native';
import PropTypes from 'prop-types';
const HEIGHT = Dimensions.get('screen').height,
WIDTH = Dimensions.get('screen').width,
beforePostion = {
center: 0.5,
bottom: 0.85,
top: 0.1,
};
export default class Toast extends Component {
/**
* message: 要提示的信息
* position: 提示信息在屏幕中的位置(x,y)
* - top 上方 居中
* - center 居中 居中
* - bottom 下方 居中
*/
static defaultProps = {
message: '',
position: 'center',
};
static propTypes = {
message: PropTypes.string,
position: PropTypes.string,
};
constructor(props) {
super(props);
this.state = {
fade: new Animated.Value(0),
};
}
/**
* 关闭toast
*/
closeToast() {
// this.state.fade.se
Animated.timing(this.state.fade, {
toValue: 0,
duration: 500,
useNativeDriver: true,
easing: Easing.elastic(1),
}).start();
}
/**
* 显示多少秒后关闭,一般调用这个
* @param {Number} seconde
*/
showAfterSecondClose(seconde) {
this.showToast();
setTimeout(() => {
this.closeToast();
}, seconde);
}
/**
* 显示toast
*/
showToast() {
Animated.timing(this.state.fade, {
toValue: 1,
duration: 500,
useNativeDriver: true,
easing: Easing.elastic(1),
}).start();
}
render() {
const messageLen = this.props.message.length,
ToastWidth = messageLen * 18 + 20,
positionLevel = beforePostion[this.props.position]
? beforePostion[this.props.position]
: 0.5;
return (
<Animated.View
style={[
styles.wrap,
{
opacity: this.state.fade,
top: HEIGHT * positionLevel - 20,
transform: [
{
scale: this.state.fade,
translateY: this.state.fade.interpolate({
inputRange: [0, 1],
outputRange: [0, -20],
}),
},
],
},
]}>
<Animated.Text ref="message" style={styles.wrapText}>
{this.props.message}
</Animated.Text>
{/* </View> */}
</Animated.View>
);
}
}
const styles = StyleSheet.create({
wrap: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
width: WIDTH,
zIndex: 999,
elevation: 999,
},
wrapText: {
color: '#fff',
fontSize: 18,
padding: 10,
backgroundColor: '#000',
borderRadius: 5,
fontWeight: 'bold',
},
});
注意:
- Toast 组件不能显示在最上方,就需要设置
zIndex
、elevation
两个样式属性zIndex
:在 Android 中无效,但在 IOS 中有效elevation
:在 Android 中有效,但在 IOS 中无效
- 其他的感觉就没什么了,学习 Animated 可以看官网的文档,写的还是比较详细的
使用
大家也看到了,我想外暴露了两个属性可以进行传递
- message:要提示的信息
- position:提示信息在屏幕中的位置
import React, {Component} from 'react';
import {View, Button} from 'react-native';
import Toast from '../../components/Toast';
export default class MyPage extends Component {
render() {
return (
<View>
<Button
title="显示Toast"
onPress={() => {
this.refs.toast.showToast();
}}
/>
<Button
title="关闭Toast"
onPress={() => {
this.refs.toast.closeToast();
}}
/>
<Button
title="2秒后消失"
onPress={() => {
this.refs.toast.showAfterSecondClose(2);
}}
/>
<Toast ref="toast" message={'显示以下Toast'} />
</View>
);
}
}
效果图:
自己封装个组件感觉还是很爽的
参考资料