React Native实现进度条弹框

React Native实现进度条弹框
我们在上传或者下载文件时候,希望有一个进度条弹框去提醒用户当前正在上传或者下载,以及当前进度,也允许用户去点击取消按钮取消上传或者下载。

1.实现进度条

import React, {
    PureComponent
} from 'react';
import {
    StyleSheet,
    View,
    Animated,
    Easing,
} from 'react-native';

class Bar extends PureComponent {

    constructor(props) {
        super(props);
        this.progress = new Animated.Value(this.props.initialProgress || 0);
    }

    static defaultProps = {
        style: styles,
        easing: Easing.inOut(Easing.ease)
    }

    componentWillReceiveProps(nextProps)  {
        if (this.props.progress >= 0 && this.props.progress !== nextProps.progress) {
            this.update(nextProps.progress);
        }
    }

    shouldComponentUpdate() {
        return false;
    }

    update(progress) {
        Animated.spring(this.progress, {
            toValue: progress
        }).start();
    }

    render() {
        return (
            <View style={[styles.background, this.props.backgroundStyle, this.props.style]}>
                <Animated.View style={[styles.fill, this.props.fillStyle, { width: this.progress.interpolate({
                    inputRange: [0, 100],
                    outputRange: [0 * this.props.style.width, 1 * this.props.style.width],
                    })} ]}
                />
            </View>
        );
    }
}

var styles = StyleSheet.create({
    background: {
        backgroundColor: '#bbbbbb',
        height: 5,
        overflow: 'hidden'
    },
    fill: {
        backgroundColor: 'rgba(0, 122, 255, 1)',
        height: 5
    }
});

export default Bar;

进度条显示我们用动画实现,避免使用state不断去重新 render渲染界面,同时设置 shouldComponentUpdate 返回值为 false,避免无用的 render。

2.实现进度条弹框

import React, {
    PropTypes,
    PureComponent
} from 'react';
import {
    View,
    StyleSheet,
    Modal,
    Text,
    Dimensions,
    TouchableOpacity
} from 'react-native';
import Bar from './Bar';

const {
    width
} = Dimensions.get('window');

class ProgressBarDialog extends PureComponent {

    constructor(props) {
        super(props);
    }

    static propTypes = {
        ...Modal.propTypes,
        title: PropTypes.string,
        canclePress: PropTypes.func,
        cancleText: PropTypes.string,
        needCancle: PropTypes.bool
    };

    static defaultProps = {
        animationType: 'none',
        transparent: true,
        progressModalVisible: false,
        onShow: () => {},
        onRequestClose: () => {},
        onOutSidePress: () => {},
        title: '上传文件',
        cancleText: '取消是',
        canclePress: () => {},
        needCancle: true
    }

    render() {
        const {
            animationType,
            transparent,
            onRequestClose,
            progress,
            title,
            canclePress,
            cancleText,
            needCancle,
            progressModalVisible
        } = this.props;
        return (
            <Modal
                animationType={animationType}
                transparent={transparent}
                visible={progressModalVisible}
                onRequestClose={onRequestClose}>
                <View style={styles.progressBarView}>
                    <View style={styles.subView}>
                        <Text style={styles.title}>
                            {title}
                        </Text>
                        <Bar
                            ref={this.refBar}
                            style={{marginLeft: 10,marginRight: 10,width:width - 80}}
                            progress={progress}
                            backgroundStyle={styles.barBackgroundStyle}
                        />
                        <View style={styles.progressContainer}>
                            <Text style={styles.progressLeftText}>
                                {`${progress}`}%
                            </Text>
                            <Text style={styles.progressRightText}>
                                {`${progress}`}/100
                            </Text>
                        </View>
                        {needCancle &&
                            <View style={styles.cancleContainer}>
                                <TouchableOpacity style={styles.cancleButton} onPress={canclePress}>
                                    <Text style={styles.cancleText}>
                                        {cancleText}
                                    </Text>
                                </TouchableOpacity>
                            </View>
                        }
                    </View>
                </View>
            </Modal>
        );
    }
}

const styles = StyleSheet.create({
    progressBarView: {
        flex:1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'rgba(0,0,0,0.2)'
    },
    barStyle: {
        marginLeft: 10,
        marginRight: 10,
        width:width - 80
    },
    progressLeftText: {
        fontSize: 14
    },
    cancleContainer: {
        justifyContent: 'center',
        alignItems: 'flex-end'
    },
    progressRightText: {
        fontSize: 14,
        color: '#666666'
    },
    barBackgroundStyle: {
        backgroundColor: '#cccccc'
    },
    progressContainer: {
        flexDirection: 'row',
        padding: 10,
        justifyContent: 'space-between'
    },
    subView: {
        marginLeft: 30,
        marginRight: 30,
        backgroundColor: '#fff',
        alignSelf: 'stretch',
        justifyContent: 'center'
    },
    progressView: {
        flexDirection: 'row',
        padding: 10,
        paddingBottom: 5,
        justifyContent: 'space-between'
    },
    title: {
        textAlign: 'left',
        padding:10,
        fontSize: 16
    },
    cancleButton: {
        padding:10
    },
    cancleText: {
        textAlign: 'right',
        paddingTop: 0,
        fontSize: 16,
        color: 'rgba(0, 122, 255, 1)'
    }
});

export default ProgressBarDialog;

props

  • modal的props - 这些都是modal的属性
    • animationType - 动画类型
    • transparent - 是否透明
    • progressModalVisible - 是否可见
    • onShow - 弹框出现
    • onRequestClose - 弹框请求消失(比如安卓按返回键会触发这个方法)
  • onOutSidePress - 点击弹框外部动作
  • title - 弹框的标题
  • cancleText - 取消的文字
  • canclePress - 取消动作
  • needCancle - 是否需要取消按钮

    3.使用代码

import React , {
    PureComponent
} from 'react';
import {
    View
} from 'react-native';

import ProgressBarDialog from './ProgressBarDialog';

class Upload extends PureComponent {

    constructor(props) {
        this.state = {
            progress: 0,
            progressModalVisible: false
        };
    }

    refProgressBar = (view) => {
        this.progressBar = view;
    }

    showProgressBar = () => {
        this.setState({
            progressModalVisible: true
        });
    }

    dismissProgressBar = () => {
        this.setState({
            progress: 0,
            progressModalVisible: false
        });
    }

    setProgressValue = (progress) => {
        this.setState({
            progress
        });
    }

    onProgressRequestClose = () => {
        this.dismissProgressBar();
    }

    canclePress = () => {
        this.dismissProgressBar();
    }

    render() {
        return (
            <View>
                <ProgressBarDialog
                    ref={this.refProgressBar}
                    progress={this.state.progress}
                    progressModalVisible={this.state.progressModalVisible}
                    onRequestClose={this.onProgressRequestClose}
                    canclePress={this.canclePress}
                    needCancle={true}
                />
            </View>
        )
    }
}

export default Upload;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值