react native (附代码)实现热更新下载进度条弹窗Modal

1. 编写进度条Bar组件

import React, { PureComponent } from 'react';
import {
  View,
  Animated,
} from 'react-native';
import PropTypes from 'prop-types';
import { getRealDP } from '../utils/utility';

const propTypes = {
  progress: PropTypes.number.isRequired,
  backgroundStyle: PropTypes.number.isRequired,
  style: PropTypes.object.isRequired,
};

/* 进度条组件 */
class Bar extends PureComponent {

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

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

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

  render() {
    return (
      <View style={[this.props.backgroundStyle, this.props.style]}>
        <Animated.View style={{
          backgroundColor: '#eb3136',
          height: getRealDP(28),
          borderRadius: getRealDP(30),
          width: this.progress.interpolate({
            inputRange: [0, 100],
            outputRange: [0, 1 * this.props.style.width],
          }) }}
        />
      </View>
    );
  }
}

Bar.propTypes = propTypes;

export default Bar;

2. 编写进度条Modal组件

import React, { PureComponent } from 'react';
import {
  View,
  Modal,
  Text,
  ImageBackground
} from 'react-native';
import Bar from '../Bar';
import hotUpdateBg from '../../assets/images/hot-update-bg.png';
import { getRealDP } from '../../utils/utility';
import styles from '../../styles/components/Modal/progress-bar-modal';

const propTypes = {
  ...Modal.propTypes,
};

const defaultProps = {
  animationType: 'none',
  transparent: true,
  progressModalVisible: false,
  onRequestClose: () => {},
};

/* 更新进度条Modal */
class ProgressBarModal extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      title: '正在下载更新文件' // 更新提示标题
    };
  }

  render() {
    const {
      animationType,
      transparent,
      onRequestClose,
      progress,
      progressModalVisible,
      totalPackageSize,
      receivedPackageSize,
    } = this.props;
    return (
      <Modal
        animationType={animationType}
        transparent={transparent}
        visible={progressModalVisible}
        onRequestClose={onRequestClose}
      >
        <View style={styles.progressBarView}>
          <ImageBackground
            source={hotUpdateBg}
            style={styles.imageBg}
          >
            <Text style={styles.title}>
              {this.state.title}
            </Text>
          </ImageBackground>
          <View style={styles.subView}>
            <Bar
              style={{ width: getRealDP(666), borderRadius: getRealDP(30) }}
              progress={progress}
              backgroundStyle={styles.barBackgroundStyle}
            />
            <Text style={styles.textPackageSize}>
              {`${receivedPackageSize}/${totalPackageSize}`}
            </Text>
          </View>
          <View style={styles.bottomContainer} />
        </View>
      </Modal>
    );
  }
}

ProgressBarModal.propTypes = propTypes;
ProgressBarModal.defaultProps = defaultProps;

export default ProgressBarModal;

样式:

import { StyleSheet } from 'react-native';

import { getRealDP } from '../../../utils/utility';

// 进度条modal样式
export default StyleSheet.create({
  imageBg: {
    width: getRealDP(780),
    height: getRealDP(224),
    justifyContent: 'center',
    alignItems: 'center'
  },
  progressBarView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0,0,0,0.2)'
  },
  // 默认进度条背景底色
  barBackgroundStyle: {
    backgroundColor: '#e0e0e0'
  },
  subView: {
    width: getRealDP(780),
    height: getRealDP(296),
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  },
  bottomContainer: {
    width: getRealDP(780),
    height: getRealDP(39),
    borderBottomLeftRadius: getRealDP(26),
    borderBottomRightRadius: getRealDP(26),
    backgroundColor: '#FFF'
  },
  textPackageSize: {
    fontSize: getRealDP(40),
    color: '#686868',
    marginTop: getRealDP(36)
  },
  title: {
    color: '#FFF',
    fontSize: getRealDP(45)
  }
});

3. 将ProgessBarModal组件添加到项目较顶层文件下渲染

        {/* 热更新下载进度modal */}
        <ProgressBarModal
          progress={this.state.progress}
          totalPackageSize={this.state.totalPackageSize}
          receivedPackageSize={this.state.receivedPackageSize}
          progressModalVisible={this.state.progressModalVisible}// 是否显示弹窗控制
        />

本文的getRealDP方法,按你们设计即可,不必引用:

/**
 * 按比例将设计的px转换成适应不同屏幕的dp
 * @param designPx 设计稿标注的px值
 * @returns {*|number}
 */
export function getRealDP(designPx) {
  return PixelRatio.roundToNearestPixel((size / 750) * SCREEN_WIDTH);
}

最终实现效果如图:

完结。

发布了36 篇原创文章 · 获赞 64 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u010379595/article/details/83512719