Flutter首页延时5秒跳转页面出现Navigator上下文错误如何解决
错误原因
你遇到的报错核心是:调用Navigator.of(context)时使用的context来自_MyAppState,这个context处于MaterialApp的上层,而Navigator是MaterialApp内部才初始化的组件,上层context无法找到对应的Navigator实例。你代码中加的Builder仅作用于body部分的组件树,跳转逻辑用的还是外层的context,所以没有解决问题。
修复方案1:拆分闪屏页为独立组件(最推荐)
把闪屏逻辑单独抽成独立的StatefulWidget,这个组件的context处于MaterialApp的下层,天然可以获取到Navigator实例,符合Flutter组件化设计规范。
改后的完整代码:
import 'mainPage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'dart:async'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: const SplashPage(), ); } } // 单独拆分的闪屏页组件 class SplashPage extends StatefulWidget { const SplashPage({super.key}); @override State<SplashPage> createState() => _SplashPageState(); } class _SplashPageState extends State<SplashPage> { @override void initState() { super.initState(); loadData(); } Future loadData() async { return Timer(const Duration(seconds: 5), () { // 如果不需要用户返回闪屏页,可把push改为pushReplacement Navigator.of(context).push( MaterialPageRoute(builder: (context) => const MainPage()), ); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.cyan, body: const Center( child: SpinKitCubeGrid(color: Colors.white, size: 50.0), ), ); } }
修复方案2:使用GlobalKey获取Navigator
如果你不想拆分组件,可以给MaterialApp绑定一个GlobalKey,直接通过key获取NavigatorState,不需要依赖context:
改后的核心代码片段:
class _MyAppState extends State<MyApp> { // 定义全局key用来获取NavigatorState final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); @override void initState() { super.initState(); loadData(); } @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, // 绑定key到MaterialApp debugShowCheckedModeBanner: false, home: Scaffold( backgroundColor: Colors.cyan, body: const Center( child: SpinKitCubeGrid(color: Colors.white, size: 50.0), ), ), ); } Future loadData() async { return Timer(const Duration(seconds: 5), () { // 直接通过key调用navigator navigatorKey.currentState?.push( MaterialPageRoute(builder: (context) => const MainPage()), ); }); } }
额外优化点
- 倒计时结束后跳转不需要调用
setState,跳转操作本身不需要更新当前页面的UI - 如果跳转到主页后不希望用户返回到闪屏页,可以把
push方法改为pushReplacement,跳转后自动销毁当前闪屏页
内容的提问来源于stack exchange,提问作者asal rad
相关产品推荐
相关产品推荐

