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

Flutter中SplashScreen启动页无法跳转到对应页面该怎么解决?

问题原因
  • 你在initState的异步方法中直接返回路由页面的逻辑无效:StatefulWidget的渲染内容完全由build方法的返回值决定,非build方法内返回的组件实例不会被框架渲染,也不会自动触发路由跳转。
  • Provider.of(context)在initState中调用时默认listen = true,会直接抛出异常,无法正常获取到User状态。
  • Flutter路由跳转需要主动调用Navigator相关API,不能靠方法返回值实现。
解决方案

方案1:主动路由跳转(适合需要固定展示启动页的场景)

启动页展示指定时长/初始化完成后,直接替换当前路由到对应页面,避免用户可以返回启动页:

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    doSomeAsyncStuff();
  }

  doSomeAsyncStuff() async {
    // 可按需调整启动页展示时长,无需要可删除该行
    await Future.delayed(const Duration(seconds: 2));
    // 非build方法内调用Provider必须加listen: false
    User user = Provider.of<User>(context, listen: false);
    if (mounted) {
      // pushReplacement替换当前路由,不会保留启动页在路由栈中
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (context) => user == null ? const LoginScreen() : const BusinessList(),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Image.asset(
          'assets/ledgerslogofinal.png',
          width: 250,
          height: 250,
        ),
      ),
    );
  }
}

方案2:build内判断返回(和无状态组件逻辑对齐)

初始化完成前展示启动页UI,初始化完成后直接返回对应业务页面,无需路由跳转:

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  bool _initCompleted = false;

  @override
  void initState() {
    super.initState();
    doSomeAsyncStuff();
  }

  doSomeAsyncStuff() async {
    // 放置你的异步初始化逻辑
    await Future.delayed(const Duration(seconds: 2));
    if (mounted) {
      setState(() => _initCompleted = true);
    }
  }

  @override
  Widget build(BuildContext context) {
    if (!_initCompleted) {
      // 未初始化完成展示启动页
      return Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: Image.asset(
            'assets/ledgerslogofinal.png',
            width: 250,
            height: 250,
          ),
        ),
      );
    }
    // 初始化完成后按用户状态返回对应页面,和无状态组件逻辑完全一致
    User user = Provider.of<User>(context);
    return user == null ? const LoginScreen() : const BusinessList();
  }
}
注意事项
  • 两种方案都添加了mounted判断,避免组件销毁后调用setState/Navigator导致异常。
  • 方案1需要确保SplashScreen处于MaterialApp的路由栈内,context可正常获取到Navigator实例。
  • 非build生命周期内调用Provider获取状态时,必须显式设置listen: false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:21:00