Flutter按钮点击报错无法跳转至ReminderHomePage求助
问题描述
点击HomePage中的按钮尝试导航到ReminderHomePage时,触发以下错误:
══╡ 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: C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_packages/flutter/src/widgets/navigator.dart 2554:9 <fn> packages/flutter/src/widgets/navigator.dart 2560:14 of packages/flutter/src/widgets/navigator.dart 2019:34 push packages/medreminder/home_page.dart 42:32 <fn> packages/flutter/src/material/ink_well.dart 1072:21 handleTap packages/flutter/src/gestures/recognizer.dart 253:24 invokeCallback packages/flutter/src/gestures/tap.dart 627:11 handleTapUp packages/flutter/src/gestures/tap.dart 306:5 [_checkUp] packages/flutter/src/gestures/tap.dart 239:7 handlePrimaryPointer packages/flutter/src/gestures/recognizer.dart 615:9 handleEvent packages/flutter/src/gestures/pointer_router.dart 98:12 [_dispatch] packages/flutter/src/gestures/pointer_router.dart 143:9 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 21:13 forEach packages/flutter/src/gestures/pointer_router.dart 141:17 [_dispatchEventToRoutes] packages/flutter/src/gestures/pointer_router.dart 127:7 route packages/flutter/src/gestures/binding.dart 460:19 handleEvent packages/flutter/src/gestures/binding.dart 440:14 dispatchEvent packages/flutter/src/rendering/binding.dart 337:11 dispatchEvent packages/flutter/src/gestures/binding.dart 395:7 [_handlePointerEventImmediately] packages/flutter/src/gestures/binding.dart 357:5 handlePointerEvent packages/flutter/src/gestures/binding.dart 314:7 [_flushPointerEventQueue] packages/flutter/src/gestures/binding.dart 295:7 [_handlePointerDataPacket] C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 1183:13 invoke1 C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 244:5 invokeOnPointerDataPacket C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 147:39 [_onPointerData] C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 653:20 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 594:14 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 288:16 loggedHandler C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 179:80 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 334:14 _checkAndCall C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 339:39 dcall Handler: "onTap" Recognizer: TapGestureRecognizer#02cb0 ════════════════════════════════════════════════════════════════════════════════════════════════════
错误原因
调用Navigator.push时使用的context是HomePage的上下文,而HomePage的build方法直接返回MaterialApp——Navigator是MaterialApp内部创建的组件,所以HomePage的上下文不属于Navigator的后代节点,无法找到Navigator实例。
解决方案
提供三种可行的解决方式:
方式一:拆分根组件与HomePage
把MaterialApp抽成独立的根组件,让HomePage作为MaterialApp的home属性,这样HomePage的上下文就处于Navigator的后代链中:
import 'package:flutter/material.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:get/get_navigation/get_navigation.dart'; import 'Reminder/ui/home_reminder.dart'; import 'Reminder/ui/widgets/button.dart'; void main() { runApp(const MyApp()); } // 新增根组件MyApp class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Medicine Reminder App'), ), body: Column( children: [ Stack( children: [ Image.asset( 'images/MenuImg.jpg', width: 600, height: 200, fit: BoxFit.cover, ), ], ), const SizedBox(height: 10.0), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( child: const Text('Button 1'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const ReminderHomePage()), ); }, ), ElevatedButton( child: const Text('Button 2'), onPressed: () {}, ), ElevatedButton( child: const Text('Button 3'), onPressed: () {}, ), ], ), ], ), ); } }
方式二:用Builder提供正确的上下文
在Scaffold外层包裹Builder组件,使用Builder提供的上下文来调用导航方法:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Builder( // 新增Builder builder: (navContext) { // 这个context是Navigator的后代 return Scaffold( appBar: AppBar( title: const Text('Medicine Reminder App'), ), body: Column( children: [ Stack( children: [ Image.asset( 'images/MenuImg.jpg', width: 600, height: 200, fit: BoxFit.cover, ), ], ), const SizedBox(height: 10.0), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( child: const Text('Button 1'), onPressed: () { Navigator.push( navContext, // 使用Builder提供的context MaterialPageRoute(builder: (context) => const ReminderHomePage()), ); }, ), ElevatedButton( child: const Text('Button 2'), onPressed: () {}, ), ElevatedButton( child: const Text('Button 3'), onPressed: () {}, ), ], ), ], ), ); }, ), ); } }
方式三:使用GetX导航(推荐)
你已经导入了GetX包,直接用GetX的导航方法无需依赖context,代码更简洁:
ElevatedButton( child: const Text('Button 1'), onPressed: () { Get.to(const ReminderHomePage()); // 直接用GetX导航 }, ),
内容的提问来源于stack exchange,提问作者NyK
相关产品推荐
相关产品推荐

