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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:40:37