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

React Native中ScrollView滚动结束时更新进度条值的问题求助

ScrollView滚动联动进度条修复方案

原代码存在的问题

  • 使用全局变量存储ScrollView尺寸,无法触发组件重渲染,导致进度条不更新
  • 未定义进度状态变量progress_count,进度条无数据绑定
  • 计算进度时未处理除数为0的边界情况,可能出现NaN值
  • 未定义widthToDp工具函数和AssetExample组件,代码无法正常运行

修复后的完整代码

import React, { useState } from 'react';
import * as Progress from 'react-native-progress';
import { Card } from 'react-native-paper';
import { Text, View, StyleSheet, ScrollView } from 'react-native';

export default function App() {
  // 用状态管理关键尺寸和进度值
  const [scrollViewHeight, setScrollViewHeight] = useState(0);
  const [scrollViewContentHeight, setScrollViewContentHeight] = useState(0);
  const [progressCount, setProgressCount] = useState(0);

  const updateProgressBar = (event) => {
    const { contentOffset } = event.nativeEvent;
    const maxScrollDistance = scrollViewContentHeight - scrollViewHeight;
    
    // 处理边界情况,避免除以0和进度值超出0-1范围
    if (maxScrollDistance <= 0) {
      setProgressCount(1);
      return;
    }
    
    const progress = Math.abs(contentOffset.y / maxScrollDistance);
    setProgressCount(Math.min(Math.max(progress, 0), 1));
  };

  return (
    <View style={styles.container}>
      <Progress.Bar
        style={{
          position: 'relative',
          bottom: 6,
          borderTopLeftRadius: 40,
          borderTopRightRadius: 40,
        }}
        height={3}
        borderWidth={0}
        progress={progressCount}
        color="red"
        width="82%" // 替换未定义的widthToDp
      />
      <ScrollView
        showsVerticalScrollIndicator={false}
        bounces={false}
        contentContainerStyle={{ paddingBottom: 0 }}
        onContentSizeChange={(width, height) => {
          setScrollViewContentHeight(height);
        }}
        onScroll={updateProgressBar}
        onLayout={(event) => {
          setScrollViewHeight(event.nativeEvent.layout.height);
        }}
        scrollEventThrottle={12}
      >
        <Text style={styles.paragraph}>
          Change code in the editor and watch it change on your phone! Save to get a 
          shareable url.
        </Text>
        <Text style={styles.paragraph}>
          Change code in the editor and watch it change on your phone! Save to get a 
          shareable url.
        </Text>
        <Text style={styles.paragraph}>
          Change code in the editor and watch it change on your phone! Save to get a 
          shareable url.
        </Text>
        <Text style={styles.paragraph}>
          Change code in the editor and watch it change on your phone! Save to get a 
          shareable url.
        </Text>
        <Card style={styles.card}>
          <Text style={styles.cardText}>示例卡片内容</Text> {/* 替换未定义的AssetExample */}
        </Card>
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'flex-start', // 调整为flex-start,避免内容居中
    paddingTop: 20,
  },
  paragraph: {
    padding: 16,
    fontSize: 16,
    lineHeight: 24,
  },
  card: {
    margin: 16,
    padding: 16,
  },
  cardText: {
    fontSize: 16,
  },
});

关键修改说明

  • 状态管理优化:用useState替代全局变量存储ScrollView高度、内容高度和进度值,确保状态变化时组件自动重渲染
  • 边界处理:增加maxScrollDistance的判断,避免除以0导致的NaN,同时用Math.min和Math.max限制进度值在0-1之间,符合Progress组件的要求
  • 未定义项处理:替换widthToDp为直接百分比值,移除未定义的AssetExample组件并替换为占位内容
  • 布局调整:修改容器的justifyContent为flex-start,避免内容被居中遮挡进度条

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 06:31:06