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

Flutter导航异常求助:Navigator操作无对应上下文的解决办法

Flutter导航异常:Navigator operation requested with a context that does not include a Navigator

问题详情

作为Flutter新手开发多页面应用,点击跳转按钮时触发上述异常,原代码和异常栈信息如下:

原main.dart代码

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

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text(
                  'Please select your language',
                  style: TextStyle(
                    fontSize:  25,
                    fontWeight: FontWeight.bold
                  ),
                ),

                const Text (
                  'You can change the language at any time',
                  style: TextStyle(
                    fontSize: 16,
                    color: Color.fromRGBO(106, 108, 123, 100)
                  ),
                ),

                DropdownButton<String>(
                  items: <String>['English', 'Hindi', 'Marathi', 'Punjabi'].map((String value) {
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Text(value),
                    );
                  }).toList(),
                  onChanged: (_) {},
                  value: 'English',
                ),

                ElevatedButton(
                    onPressed: (){
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => MobileNumber()//Exception on this line.

                          )
                      );
                    },
                    child: const Text("NEXT"),
                )
              ],
            ),
          )
        )
    );
  }
}

原MobileNumber.dart代码

import 'package:flutter/material.dart';

class MobileNumber extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Text("Mobile Number Page"),
      ),
    );
  }
}

异常栈信息

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.

The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
When the exception was thrown, this was the stack: 
#0      Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2554:9)
#1      Navigator.of (package:flutter/src/widgets/navigator.dart:2561:6)
#2      Navigator.push (package:flutter/src/widgets/navigator.dart:2019:22)
#3      MyAppState.build.<anonymous closure> (package:liveasy_task_flutter/main.dart:52:33)
#4      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
#5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
#6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
#7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
#8      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
#9      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
#10     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#12     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#13     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#14     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#15     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
#16     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
#17     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
#18     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
#19     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
#20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
#21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
#22     _invoke1 (dart:ui/hooks.dart:167:13)
#23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#1dfff
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(183.0, 459.8)
  finalLocalPosition: Offset(32.0, 18.0)
  button: 1
  sent tap down

原因分析

  1. 上下文层级错误:你在MyAppState中使用的context是MyApp组件的上下文,而MaterialApp是在这个上下文之后构建的,这个context不在MaterialApp内部的导航器(Navigator)上下文树里,所以调用Navigator.push时找不到对应的Navigator实例。
  2. 重复创建MaterialApp:MobileNumber页面里又返回了一个MaterialApp,一个Flutter应用只需要一个根MaterialApp,重复创建会导致导航逻辑混乱,也不符合开发规范。

解决方法

核心修复点

  • 确保调用Navigator.push时使用的context是MaterialApp的子上下文。
  • 移除MobileNumber页面中的MaterialApp,只保留Scaffold。

方案一:拆分首页组件(推荐)

把首页的Scaffold内容抽成单独的组件,让MaterialApp作为根组件,这样首页内部的context自然属于导航器上下文树:

修改后的main.dart

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(), // 首页抽为独立组件
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

class HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'Please select your language',
              style: TextStyle(
                fontSize: 25,
                fontWeight: FontWeight.bold,
              ),
            ),
            const Text(
              'You can change the language at any time',
              style: TextStyle(
                fontSize: 16,
                color: Color.fromRGBO(106, 108, 123, 100),
              ),
            ),
            DropdownButton<String>(
              items: <String>['English', 'Hindi', 'Marathi', 'Punjabi']
                  .map((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
              onChanged: (_) {},
              value: 'English',
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const MobileNumber(),
                  ),
                );
              },
              child: const Text("NEXT"),
            ),
          ],
        ),
      ),
    );
  }
}

修改后的MobileNumber.dart

import 'package:flutter/material.dart';

class MobileNumber extends StatelessWidget {
  const MobileNumber({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Text("Mobile Number Page"),
    );
  }
}

方案二:使用Builder包裹按钮

如果不想拆分组件,可以在ElevatedButton外层套一个Builder,它会提供一个属于MaterialApp上下文树的context:

// 替换原代码中的ElevatedButton部分
Builder(
  builder: (context) {
    return ElevatedButton(
      onPressed: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => const MobileNumber(),
          ),
        );
      },
      child: const Text("NEXT"),
    );
  },
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:55:28