一、简介
之前和大家分享的自定义View内容,我们知道自定义View一般分为三个步骤:
(1)定义属性、状态
(2)定义组件行为
(3)绘制布局
(4)定义样式
二、分析
App中的提示(Toast)想必大家都不陌生,RN中也提供了ToastAndroid,但是由于仅能在Android平台使用,所以出现了很多开源的三方依赖库,例如react-native-root-toast等等。那么这种该如何实现呢?
1、Toast提示框大致由三部分组成:
(2)显示时长
(3)显示位置
(4)背景
我们可以根据这些来定义基本属性。
2、Toast的的状态分为两种:
(1)显示
(2)隐藏
显示/隐藏的行为我们可以通过state状态来控制。
分析了以上思路,那么就是撸码的节奏了。
三、实现
(1)定义属性、状态:
// 定义props static propTypes = { textStyle: ViewPropTypes.style,contentStyle: ViewPropTypes.style,containerStyle: ViewPropTypes.style,position: PropTypes.oneOf([ 'top','center','bottom' ]) } //初始化 默认 props static defaultProps = { position: 'center' } constructor(props) { super(props); this.state = { text: '',isShow: false,opacityAnimate: new Animated.Value(OPACITY) // 动画 值初始化 }; // 当前显示状态 this.isShow = false; // 初始化默认显示时长为SHORT this.duration = DURATION.SHORT; }(2)定义组件行为
/** * 显示 */ show(text,duration) { if(duration >= DURATION.LONG) { this.duration = DURATION.LONG; } else { this.duration = DURATION.SHORT; } // 显示 this.setState({ text: text,isShow: true }); this.isShow = true; this.state.opacityAnimate.setValue(OPACITY); // 执行隐藏操作 this.hide(); } /** * 隐藏 */ hide() { // 隐藏状态下不执行操作 if(!this.isShow) { return; } this.animateTimer && clearTimeout(this.animateTimer); this.animateTimer = setTimeout(()=>{ // 开启动画 Animated.timing( this.state.opacityAnimate,{ toValue: 0.0,duration: 600 } ).start(()=>{ // 动画结束后,初始化状态 this.setState({ isShow: false }) this.isShow = false; }) },this.duration); }(3)绘制布局
render() { let top; switch(this.props.position){ case 'top': top = 30; break; case 'center': top = height / 2; break; case 'bottom': top = height - 100; break; default: break; } return this.state.isShow ? <View pointerEvents={ 'none' } style={[ styles.container,{ top: top } ]}> <Animated.View style={[ styles.content,this.props.contentStyle,{ opacity: this.state.opacityAnimate } ]} > <Text style={[ styles.text,this.props.textStyle ]}> { this.state.text } </Text> </Animated.View> </View> : null; } }(4)定义样式(建议单独封装样式,在组件中引用,遵循模块化开发)
const styles = StyleSheet.create({ container: { position: 'absolute',left: 0,right: 0,alignItems: 'center' },content: { backgroundColor: '#000000',opacity: OPACITY,borderRadius: 20,padding: 10 },text: { color: '#FFFFFF',fontSize: 14,fontFamily: 'PingFang-SC-Regular' } })以上代码很简单,基本使用了Animated + View 的方式来实现。最后贴上完整代码:
/** * Toast 提示 */ import React,{ Component,PropTypes } from 'react'; import { View,Text,Animated,Dimensions,StyleSheet,ViewPropTypes } from 'react-native'; // 设备屏幕宽高 const { width,height } = Dimensions.get('window'); // Toast提示框透明度 const OPACITY = 0.8; // 显示时长 export const DURATION = { LONG: 1500,SHORT: 500 }; export default class Toast extends Component { // 定义props static propTypes = { textStyle: ViewPropTypes.style,opacityAnimate: new Animated.Value(OPACITY) // 动画 值初始化 }; // 当前显示状态 this.isShow = false; // 初始化默认显示时长为SHORT this.duration = DURATION.SHORT; } componentWillUnmount() { // 在页面生命周期结束时,解除定时器,避免内存泄漏 this.animateTimer && clearTimeout(this.animateTimer); } /** * 显示 */ show(text,this.duration); } render() { let top; switch(this.props.position){ case 'top': top = 30; break; case 'center': top = height / 2; break; case 'bottom': top = height - 100; break; default: break; } return this.state.isShow ? <View pointerEvents={ 'none' } style={[ styles.container,this.props.textStyle ]}> { this.state.text } </Text> </Animated.View> </View> : null; } } const styles = StyleSheet.create({ container: { position: 'absolute',fontFamily: 'PingFang-SC-Regular' } })
四、使用
1、导入
import Toast from './components/Toast'; <Toast ref="toast" position={'bottom'} />
2、调用:
/** * 显示 */ showToast() { this.refs.toast.show('中奖了...',1200); }原文链接:https://www.f2er.com/react/302478.html