React Native实现加载屏幕平滑淡出切换至首页的方法
实现加载屏幕到天气页面的平滑淡入切换效果
针对你的React Native天气应用,这里提供两种可行的平滑切换实现方式:
方案一:使用Animated API实现精细过渡控制
通过Animated组件控制加载页和天气页的透明度,实现淡入淡出的平滑切换,相比条件渲染更灵活:
import { useState, useEffect, useRef } from 'react'; import { View, Animated, StyleSheet } from 'react-native'; export default function Home() { const [isLoading, setIsLoading] = useState(true) const [temperature, setTemperature] = useState(0) const [weatherCondition, setWeatherCondition] = useState(null) // 初始化动画值:加载页初始透明度1,天气页初始透明度0 const loadingOpacity = useRef(new Animated.Value(1)).current; const weatherOpacity = useRef(new Animated.Value(0)).current; const lat = 60 const lon = 24 useEffect(() => { // 移除不必要的6秒超时,直接请求API fetch(`http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&APPID=${API_KEY}&units=metric`) .then(res => res.json()) .then(json => { setTemperature(json.main.temp) setWeatherCondition(json.weather[0].main) // API请求完成后触发同步动画 Animated.parallel([ Animated.timing(loadingOpacity, { toValue: 0, duration: 500, // 自定义动画时长 useNativeDriver: true, }), Animated.timing(weatherOpacity, { toValue: 1, duration: 500, useNativeDriver: true, }) ]).start(() => { // 动画完成后再隐藏加载页,避免布局闪烁 setIsLoading(false); }); }) .catch((e) => console.log(e)) },[]); return ( <View style={styles.container}> {/* 加载页:绝对定位覆盖在天气页上方,通过透明度控制显示 */} {isLoading && ( <Animated.View style={{...StyleSheet.absoluteFillObject, opacity: loadingOpacity}}> <LoadingScreen/> </Animated.View> )} {/* 天气页:通过透明度控制淡入 */} <Animated.View style={{opacity: weatherOpacity}}> <Weather weather={weatherCondition} temperature={temperature}/> </Animated.View> </View> ) }
关键说明:
- 用
Animated.parallel同步执行两个动画,让加载页淡出、天气页淡入同时进行 StyleSheet.absoluteFillObject确保加载页铺满容器,完全覆盖天气页- 动画完成后再更新
isLoading状态,避免加载页提前消失导致的视觉断层
方案二:使用LayoutAnimation快速实现
如果想要极简的代码改动,React Native内置的LayoutAnimation可以自动处理组件显示/隐藏的过渡动画:
import { useState, useEffect } from 'react'; import { View, LayoutAnimation, UIManager, Platform } from 'react-native'; // Android需要手动开启布局动画支持 if (Platform.OS === 'android') { if (UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } } export default function Home() { const [isLoading, setIsLoading] = useState(true) const [temperature, setTemperature] = useState(0) const [weatherCondition, setWeatherCondition] = useState(null) const lat = 60 const lon = 24 useEffect(() => { fetch(`http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&APPID=${API_KEY}&units=metric`) .then(res => res.json()) .then(json => { setTemperature(json.main.temp) setWeatherCondition(json.weather[0].main) // 设置淡入淡出动画预设 LayoutAnimation.configureNext(LayoutAnimation.Presets.fade); setIsLoading(false); }) .catch((e) => console.log(e)) },[]); return ( <View style={styles.container}> {isLoading ? <LoadingScreen/> : <Weather weather={weatherCondition} temperature={temperature}/> } </View> ) }
关键说明:
LayoutAnimation.Presets.fade是官方内置的淡入淡出动画,也可以自定义动画时长、缓动效果- Android需要额外开启实验性布局动画支持,代码中已做兼容处理
- 这种方式几乎不需要修改原有结构,适合快速实现基础平滑切换
另外建议:你原代码中的6秒超时可以直接移除,API请求完成后立即触发动画,更贴合实际业务逻辑。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

