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

Flutter如何从启动页(splash screen)跳转页面 出现Navigator上下文错误怎么解决

问题修复方案

错误原因

报错核心是你调用Navigator时使用的context属于MainPage组件,而Navigator是在MaterialApp内部才初始化的,MainPage是MaterialApp的父组件,父组件的context无法访问到子组件内部的Navigator实例。
另外你在build方法中直接调用异步方法getRedirectPage,会导致页面每次重绘都重复发起请求,属于逻辑错误。

修复步骤

  • 第一步:调整组件结构,将MaterialApp提到最外层,把启动页逻辑拆分为独立的子组件,保证跳转用的context在MaterialApp的子树内
  • 第二步:将异步请求逻辑移到initState中,避免重复执行

修复后完整代码

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ID - IoT',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SplashScreen(),
    );
  }
}

class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    // 初始化阶段调用跳转逻辑,仅执行一次
    getRedirectPage(context);
  }

  Future<void> getRedirectPage(BuildContext context) async {
    await initializeSharedPrefs();
    ServerResponse serverResponse = await makeRequestToServer(null);
    if (serverResponse.state.isNotEmpty) {
      if (serverResponse.state == "true") {
        if (serverResponse.redirect == "login") {
          Navigator.of(context).pushReplacement(
            PageRouteBuilder(pageBuilder: (_,__,___)=> const LoginPage())
          );
        } else {
          Navigator.of(context).pushReplacement(
            PageRouteBuilder(pageBuilder: (_,__,___)=> const Homepage())
          );
        }
      } else {
        showAlertDialog(context, "Server error", "Something went wrong: ${serverResponse.msg}");
      }
    } else {
      showAlertDialog(context, "Server error", "Something went wrong: ${serverResponse.msg}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        image: DecorationImage(
          image: AssetImage('assets/images/background.jpeg'),
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

额外优化建议

  • 可以给跳转逻辑加个最低展示时长,避免请求响应太快导致启动页一闪而过体验差,可搭配Future.delayed控制至少显示1~2秒
  • 建议给请求逻辑加异常捕获,避免接口超时、报错导致页面卡住

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:15:02