React Native中的Javascript进度栏

时间:2019-02-03 21:18:00

标签: javascript reactjs react-native progress-bar

我要在react native中实现类似Instagram故事的功能,我需要在顶部实现进度条以指示当前故事的进度。 目前,我有一个计时器,一旦故事开始播放,该计时器便开始计时:

onStart = (timeout: number, total: number) => {
    const updateFrequncy = 1000 / PROGRESS_BAR_TICK;
    this._timer = this.props.setInterval(() => {
        this.setState(state => ({
            progress:
                state.progress +
                (PROGRESS_BAR_SPEED * PROGRESS_BAR_RANGE * updateFrequncy) /
                    total,
        }));
    }, PROGRESS_BAR_TICK);
};

,我正在将进度状态传递到进度栏。 (一个Animated.View组件,将当前进度呈现为样式的宽度)。 因此,基本上,由于setState,它将每隔PROGRESS_BAR_TICK毫秒渲染一次。我面临的问题是-由于JS是单线程的,因此,如果有另一个事件占用了该线程,或者在某些低端设备上JS线程运行缓慢,进度条将变得混乱。

有什么建议可以使其更流畅?

1 个答案:

答案 0 :(得分:0)

除了使用setInterval之外,您还可以启动Animated.timing动画来为故事设置相同的持续时间吗?如果用户暂停了故事,则您应该可以在动画上调用stop()来停止故事,然后以预期的剩余持续时间再次恢复故事。

另外,我建议不要在进度条上使用scaleXtranslateX,它们可以完全在本机线程上运行,而不是设置进度条的宽度。

这是一个部分示例,其中缺少触发onStartonPause的方式,因为我不确定其余组件的外观。


class Thing {
  _progressValue = new Animated.Value(0);

  onStart = (duration: number) => {
    this._animation = Animated.timing(this._progressValue, {
      duration: duration,
      toValue: 100,
      easing: Easing.linear,
      useNativeDriver: true,
    }).start();
  };

  onPause = () => {
    if (this._animation != null) this._animation.stop();
  };

  render() {
    return (
      <View style={{width: 100, height: 5, backgroundColor: 'green'}}>
        <Animated.View style={{width: 100, height: 5, backgroundColor: 'red', transform: [{translateX: this._progressValue}]}} />
      </View>
    );
  }
}