加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

React Native 自定义实现【Toast】提示框

发布时间:2020-12-15 06:43:37 所属栏目:百科 来源:网络整理
导读:今天和大家分享一篇自定义View的内容。 一、简介 之前和大家分享的自定义View内容,我们知道自定义View一般分为三个步骤: (1)定义属性、状态 (2)定义组件行为 (3)绘制布局 (4)定义样式 二、分析 App中的提示(Toast)想必大家都不陌生,RN中也提供

今天和大家分享一篇自定义View的内容。


一、简介


之前和大家分享的自定义View内容,我们知道自定义View一般分为三个步骤:


(1)定义属性、状态

(2)定义组件行为

(3)绘制布局

(4)定义样式


二、分析


App中的提示(Toast)想必大家都不陌生,RN中也提供了ToastAndroid,但是由于仅能在Android平台使用,所以出现了很多开源的三方依赖库,例如react-native-root-toast等等。那么这种该如何实现呢?

1、Toast提示框大致由三部分组成:

(1)显示文字

(2)显示时长

(3)显示位置

(4)背景

我们可以根据这些来定义基本属性。


2、Toast的的状态分为两种:

(1)显示

(2)隐藏

显示/隐藏的行为我们可以通过state状态来控制。


3、在Toast显示隐藏时,可以用透明度动画来增加用户体验

分析了以上思路,那么就是撸码的节奏了。


三、实现


(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);
  }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读