You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Expo自定义进度条:基于总步数的宽度计算数学实现

React Native Expo 自定义进度条:宽度计算与动画实现

一、宽度计算的核心公式

要让进度条宽度随步骤按比例变化,核心逻辑是:
当前进度宽度 = (当前步骤 / 总步数) × 进度条容器的总宽度

这个公式的优势:

  • 适配不同尺寸的进度条容器,不需要硬写固定增量(比如你原来的50)
  • 进度始终和步骤占比严格对应,总步数变化时也能自动适配

二、代码修复与动画实现

你的现有代码存在useEffect缺少依赖项、普通state无法实现动画等问题,下面是修正后的完整代码:

import React, { useState, useEffect, useRef } from 'react';
import { View, Text, Animated } from 'react-native';

const ProgressBar = ({ step, request }) => {
  const [steps, setSteps] = useState(0);
  const [accessToken, setAccessToken] = useState(null);
  const [containerWidth, setContainerWidth] = useState(0);
  // 用Animated.Value管理宽度,实现动画效果
  const animatedWidth = useRef(new Animated.Value(0)).current;

  // 获取token
  useEffect(() => {
    const getToken = async () => {
      const token = await token.get();
      setAccessToken(token);
    };
    getToken();
  }, []);

  // 根据token和request更新总步数
  useEffect(() => {
    if (accessToken) {
      setSteps(request === 1 ? 6 : 7);
    } else {
      setSteps(3);
    }
  }, [accessToken, request]);

  // 获取进度条容器的总宽度
  const handleContainerLayout = (e) => {
    const width = e.nativeEvent.layout.width;
    setContainerWidth(width);
    // 初始化宽度动画
    Animated.timing(animatedWidth, {
      toValue: (step / steps) * width,
      duration: 300,
      useNativeDriver: false,
    }).start();
  };

  // 当step或steps变化时,更新进度条宽度(带动画)
  useEffect(() => {
    if (containerWidth === 0) return;
    Animated.timing(animatedWidth, {
      toValue: (step / steps) * containerWidth,
      duration: 300, // 可根据需求调整动画时长
      useNativeDriver: false,
    }).start();
  }, [step, steps, containerWidth]);

  return (
    <View style={{ flexDirection: 'row', alignItems: 'center' }}>
      <View style={styles.progressBar} onLayout={handleContainerLayout}>
        <Animated.View
          style={[styles.progress, { width: animatedWidth }]}
        />
      </View>
      <Text style={styles.progressText}>{step}/{steps}</Text>
    </View>
  );
};

// 示例样式,可按需调整
const styles = {
  progressBar: {
    height: 8,
    borderRadius: 4,
    backgroundColor: '#e0e0e0',
    marginRight: 10,
    flex: 1,
  },
  progress: {
    height: '100%',
    borderRadius: 4,
    backgroundColor: '#2196F3',
  },
  progressText: {
    fontSize: 14,
    color: '#666',
  },
};

export default ProgressBar;

关键修改说明:

  • 改用Animated.Value和Animated.timing实现平滑的宽度变化动画
  • 单独存储进度条容器宽度作为计算基准值
  • 给每个useEffect添加正确的依赖项,避免无效渲染
  • 拆分总步数更新逻辑,代码结构更清晰

内容的提问来源于stack exchange,提问作者Wafa Tu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:50:33