業務須要專門看了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);
複製代碼