如何为react-native-webview添加淡入淡出切换动画?
React Native WebView 淡入淡出过渡失效问题解决
问题原因
WebView 是原生渲染组件,和普通 RN View 的渲染生命周期不同步:
- 直接用
Animated.View包裹时,WebView 可能在动画启动前就已完成加载并显示,覆盖了外层的 opacity 动画效果 - WebView 并非 Animated 原生支持的组件,外层 Animated.View 的样式无法完全同步到 WebView 的原生视图层
解决方案
步骤1:将 WebView 包装为 Animated 组件
通过 Animated.createAnimatedComponent 把 WebView 转换为支持 Animated 样式的组件,让 opacity 动画直接作用在 WebView 本身。
步骤2:同步动画与 WebView 加载状态
通过初始 opacity 为 0 + 加载状态控制,确保动画和 WebView 显示时机对齐。
完整代码
import { useRef, useCallback } from 'react'; import { Animated } from 'react-native'; import { WebView } from 'react-native-webview'; import { useFocusEffect } from '@react-navigation/native'; // 包装WebView为支持Animated的组件 const AnimatedWebView = Animated.createAnimatedComponent(WebView); export const FadeInWebView = props => { const fadeAnim = useRef(new Animated.Value(0)).current; const webViewRef = useRef(null); useFocusEffect(useCallback(() => { // 标签页聚焦:执行淡入动画 Animated.timing(fadeAnim, { toValue: 1, duration: 500, useNativeDriver: true, }).start(); return () => { // 标签页失焦:执行淡出动画,完成后暂停加载优化性能 Animated.timing(fadeAnim, { toValue: 0, duration: 250, useNativeDriver: true, }).start(() => { webViewRef.current?.stopLoading(); }); }; }, [fadeAnim])); return ( <AnimatedWebView ref={webViewRef} source={{ uri: 'https://expo.dev' }} style={{ flex: 1, opacity: fadeAnim }} // 初始加载状态配合opacity:0,避免提前显示 startInLoadingState={true} /> ); };
额外优化点
- 淡出动画完成后调用
stopLoading,减少后台不必要的网络请求和资源占用 - 使用
useCallback包裹 useFocusEffect 的回调,避免不必要的重渲染
内容的提问来源于stack exchange,提问作者Mihkuno
相关产品推荐
相关产品推荐

