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

React Native Navigation点击屏幕时如何重新渲染并触发动画?

问题分析与解决方案

核心问题

你的进度条动画只执行一次的原因是:首次动画完成后,Animated.Value 的值已经停在目标宽度finalWidth,后续切换回SettingsScreen触发focus事件时,动画的起始值和目标值一致,因此不会再次执行动画。

修复步骤

每次触发focus事件时,需要先将进度条宽度重置为初始值0,再执行动画。以下是两种可行的修改方案:

方案1:在focus监听器中重置动画值

修改ProgressBar组件的useEffect部分:

const ProgressBar = ({ navigation }) => {
  const barWidth = React.useRef(new Animated.Value(0)).current;
  const finalWidth = width / 2;

  React.useEffect(() => {
    const listener = navigation.addListener("focus", () => {
      // 先瞬间重置宽度为0
      Animated.timing(barWidth, {
        toValue: 0,
        duration: 0, // 无过渡直接重置
        useNativeDriver: false,
      }).start(() => {
        // 重置完成后播放弹簧动画
        Animated.spring(barWidth, {
          toValue: finalWidth,
          bounciness: 10,
          speed: 2,
          useNativeDriver: false,
        }).start();
      });
    });

    // 组件卸载时移除监听器
    return () => listener();
  }, [navigation]);

  return (
    <View style={style.contentContainer}>
      <Animated.View style={[style.progressBar, { width: barWidth }]} />
    </View>
  );
};

方案2:使用useFocusEffect(更贴合导航场景)

useFocusEffect是React Navigation提供的专门用于处理屏幕聚焦状态的Hook,比手动添加focus监听器更简洁:

import { useFocusEffect } from '@react-navigation/native';

const ProgressBar = () => {
  const barWidth = React.useRef(new Animated.Value(0)).current;
  const finalWidth = width / 2;

  useFocusEffect(
    React.useCallback(() => {
      // 重置并播放动画
      Animated.timing(barWidth, {
        toValue: 0,
        duration: 0,
        useNativeDriver: false,
      }).start(() => {
        Animated.spring(barWidth, {
          toValue: finalWidth,
          bounciness: 10,
          speed: 2,
          useNativeDriver: false,
        }).start();
      });
    }, [])
  );

  return (
    <View style={style.contentContainer}>
      <Animated.View style={[style.progressBar, { width: barWidth }]} />
    </View>
  );
};

额外优化

  • 你在SettingsScreen中传递了isFocused给ProgressBar但未使用,若需要基于聚焦状态做更多逻辑,可以将isFocused加入依赖项,结合useEffect触发动画。
  • 确保FlatList的renderItem不会因为不必要的重渲染导致性能问题,当前代码中keyExtractor使用索引是可行的,但如果数据有唯一ID建议替换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:25:32