业务须要专门看了react native的Animate动画作出一个Toast提示框react
// Toast
import React from 'react';
import { Animated, Text, View, Easing, Dimensions, Modal,StyleSheet } from 'react-native';
const widthScreen = Dimensions.get('window').width
export default class Toast extends React.Component {
state = {
fadeAnim: new Animated.Value(0), // 透明度初始值设为0
text: '', // 显示文本
refToast: false, // 是否经过ref绑定
timer: '', // 定时器
callback:null, // 回调
}
// 执行动画
shwoToast = (duration = 2000) => {
Animated.sequence([
Animated.timing( // 随时间变化而执行动画
this.state.fadeAnim, // 动画中的变量值
{
easing: Easing.linear,
toValue: 1, // 透明度最终变为1,即彻底不透明
duration: duration, // 让动画持续一段时间
}
),
]).start(); // 开始执行动画
}
show = (text, duration,callback) => {
this.setTiner(duration)
this.setState({ text, refToast: true })
this.state.fadeAnim.setValue(0) // 必需要每次执行都变动一次为0,才能使得动画从0隐藏到1显示
this.shwoToast() // 执行动画
callback&&callback() // 回调
}
setTiner = () => {
this.state.timer = setTimeout(() => {
this.setState({ refToast: false })
clearTimeout(this.state.timer)
}, 2000);
}
render() {
let { fadeAnim, refToast } = this.state
let { showToast, duration } = this.props
let { width, left } = styles.container
let text = refToast ? this.state.text : this.props.text
if (!refToast && showToast) { // 布尔值判断是否显示Toast
this.state.fadeAnim.setValue(0) // 必需要每次执行都变动一次为0,才能使得动画从0隐藏到1显示
this.show(text, duration) // 执行动画
showToast = false // 执行以后要变为false,不在执行
}
// 检查显示文字内容过多宽度变大
if (text && text.length > 14) {
width = 200
left = (widthScreen / 2) - 100
} else {
width = 140
left = (widthScreen / 2) - 70
}
const opacity = fadeAnim.interpolate({
inputRange: [0, 0.5, 1], // 显示
outputRange: [0, 5, 0] // 隐藏
});
return (
<View>
<Modal
animationType="none"
transparent={refToast}
visible={refToast}
>
<Animated.View // 使用专门的可动画化的View组件
style={{
...styles.container,
opacity: opacity, // 将透明度指定为动画变量值
width,
left
}}
>
<View style={styles.bodyView}>
<Text style={styles.bodyText}>{text}</Text>
</View>
</Animated.View>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
bottom: 80,
backgroundColor: '#ddd',
borderRadius: 10,
height: 'auto',
padding: 15,
width: 140,
left: (widthScreen / 2) - 70,
zIndex: 9991,
},
bodyView: {},
bodyText: {
textAlign: 'center'
}
})
复制代码
一、咱们须要引入toast文件android
// app.js
import ToastView from './src/components/toast/Index';
复制代码
二、在app.js组件中注册redux
// app.js
render() {
return (
<Provider store={store}>
<View style={styles.app}>
<ToastView ref="toast" />
<StackNavigator />
</View>
</Provider>
);
}
复制代码
三、须要定义一个全局变量,用来全局使用react-native
// app.js
global.Toast = '' // 全局Toast弹框
复制代码
四、在节点渲染完成以后须要获取refs的绑定bash
app.js
componentDidMount() {
Toast = this.refs.toast // 绑定Toast节点
}
复制代码
五、完整代码,我这里包含了redux和路由app
// app.js
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, BackHandler, ToastAndroid, Dimensions } from 'react-native';
import StackNavigator from './src/router/StackNavigator';
import { Provider } from 'react-redux';
import store from './src/redux/store';
import ToastView from './src/components/toast/Index';
const screenWidth = Dimensions.get('window').width;
import PreventDoublePress from './src/utils/PreventDoublePress'
// 禁止警告
console.disableYellowBox = true;
console.warn('YellowBox is disabled.');
// 打包以后清除全部console警告
if (!__DEV__) {
global.console = {
info: () => { },
log: () => { },
warn: () => { },
debug: () => { },
error: () => { }
};
}
// 全局
global.loginToken = '' // 登陆token
global.Toast = '' // 全局Toast弹框
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
lastBackPressed: 0
}
}
// 页面建立的时候对物理按钮进行监听
componentWillMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('hardwareBackPress', this.BackHandler);
}
}
// 页面摧毁的时候销毁监听
componentWillUnmount() {
if (Platform.OS === 'android') {
BackHandler.removeEventListener('hardwareBackPress', this.BackHandler);
}
}
componentDidMount() {
Toast = this.refs.toast // 绑定Toast节点
}
// 物理返回键 事件触发
BackHandler = () => {
if (this.state.lastBackPressed && this.state.lastBackPressed + 2000 >= Date.now()) {
BackHandler.exitApp()
return false
}
this.state.lastBackPressed = Date.now()
ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT)
return true
}
render() {
return (
<Provider store={store}>
<View style={styles.app}>
<ToastView ref="toast" />
<StackNavigator />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
app: {
flex: 1,
flexDirection: 'row'
},
toast: {
position: 'absolute',
bottom: 50,
left: screenWidth / 2,
backgroundColor: '#aaa',
width: 100,
height: 'auto',
zIndex: 999
},
toastText: {
// color:'#000'
}
});
复制代码
使用方法:在任意一个业务页面中 直接 Toast.show(显示内容
)ide
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { getDate } from '../../../redux/actions'
import { connect } from 'react-redux';
import styles from './Style'
// 首页
class Index extends Component {
showtoast = () => {
Toast.show(`Toast显示内容`)
}
render() {
return (
<View style={styles.container}>
<Text onPress={() => this.showtoast()}>点击显示Toast框</Text>
</View>
);
}
}
const mapStateToProps = state => ({
store: state.store
})
export default connect(mapStateToProps)(Index);
复制代码
Toast.show() 里面能够提交有三个参数 参数1:显示的文本 参数2: 显示时长 默认2000毫秒 参数3:回调函数 使用方法:函数
Toast.show('Toast内容',2000,() => {
// 作些什么
})
复制代码
最终效果flex
也能够在当前页面单独引用动画
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { getDate } from '../../../redux/actions'
import { connect } from 'react-redux';
import styles from './Style'
import Toast from '../../../components/toast/Index'
// 首页
class Index extends Component {
constructor(props) {
super(props);
this.state = {
text:'',
show:false
}
}
showtoast = () => {
this.setState({
text:'Toast显示内容',
show:true
})
}
render() {
return (
<View style={styles.container}>
<Toast
text={this.state.text}
show={this.state.show}
/>
<Text onPress={() => this.showtoast()}>点击显示Toast框</Text>
</View>
);
}
}
const mapStateToProps = state => ({
store: state.store
})
export default connect(mapStateToProps)(Index);
复制代码