Flutter如何实现闪屏页动画在所有API数据加载完成后再结束跳转
问题背景
现有Flutter应用闪屏页配置了固定3秒动画时长,初始化阶段并行加载鉴权、品牌列表、视频列表、分类列表等前置接口数据,弱网场景下会出现动画播放完成但接口未返回,后续页面拿不到初始化数据导致异常的问题,需要调整逻辑,保证所有前置数据加载完成后再跳转,同时不破坏原有闪屏动画体验。
核心实现逻辑
跳转需要同时满足两个前置条件,缺一不可:
- 闪屏动画至少播放完预设的最短时长,避免接口响应过快导致动画闪跳
- 所有前置初始化接口、鉴权逻辑全部执行完成(包含异常兜底处理,避免无限卡加载)
放弃组件自带的固定时长自动跳转能力,自行监听所有加载任务状态,满足条件后手动触发路由跳转。
具体改造步骤
- 第一步:改造所有预加载方法,统一返回Future
把Provider中原本无返回值的chekingAuthVariables、getBrands、getVideos、getCategoryList方法全部改为async异步方法,返回Future<void>,内部做好异常捕获,请求结束后调用notifyListeners同步状态。参考改造示例:
Future<void> getBrands() async { try { // 原有接口请求、数据赋值逻辑 brands = await brandApi.fetchList(); } catch (e) { // 按需处理异常,比如打印日志、标记错误状态 debugPrint('品牌列表加载失败: $e'); } finally { notifyListeners(); } }
- 第二步:改造闪屏页状态逻辑,自行控制跳转时机
移除原有固定时长自动跳转的配置,用Future.wait并行等待所有加载任务+最短动画延迟任务,任务全部完成后手动执行路由替换,同时增加防重复跳转、组件挂载状态判断,避免报错。完整代码如下:
class _SplashPageState extends State<SplashPage> { // 防重复跳转标记 bool _hasNavigated = false; // 闪屏最短展示时长,和原动画时长保持一致即可 final int _minSplashDisplayMs = 3000; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { await _loadInitDataAndJump(); }); } Future<void> _loadInitDataAndJump() async { final authProvider = Provider.of<AuthProvider>(context, listen: false); final loadingProvider = Provider.of<LoadingProvider>(context, listen: false); final catProvider = Provider.of<CatProviders>(context, listen: false); try { // 并行等待所有任务完成 await Future.wait([ // 最短时长延迟任务,保证动画完整播放 Future.delayed(Duration(milliseconds: _minSplashDisplayMs)), // 所有初始化任务 authProvider.chekingAuthVariables(), loadingProvider.getBrands(), loadingProvider.getVideos(), catProvider.getCategoryList(), ]); } catch (e) { debugPrint('初始化任务执行异常: $e'); // 可按需增加错误提示、重试逻辑 } finally { // 页面未销毁、未执行过跳转才触发路由 if (mounted && !_hasNavigated) { _hasNavigated = true; Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => const MainTabPage()), ); } } } @override Widget build(BuildContext context) { return AnimatedSplashScreen( backgroundColor: ColorManager.tabBottonNonActive, // 设为极大值,禁用组件自带的自动跳转逻辑 duration: 999999, splash: 'assets/splash.png', nextScreen: const SizedBox.shrink(), splashTransition: SplashTransition.slideTransition, ); } }
优化建议
- 不要忽略异常捕获,弱网下接口请求失败如果没有兜底,会导致
Future.wait直接抛出异常中断流程,可以在异常分支增加网络错误提示、重试按钮,避免用户无限卡在闪屏页 - 如果部分接口加载失败不影响主流程,可以把对应方法的异常在内部消化,不要让异常抛出到
Future.wait层,保证主流程能正常跳转 - 如果需要更精细的加载状态展示,可以在闪屏页底部加加载进度条、加载状态提示,不用一直展示静态splash图
内容的提问来源于stack exchange,提问作者Sarmed MQ Berwari
相关产品推荐
相关产品推荐

