Flutter Web运行官方导航代码报上下文不包含Navigator的Navigator操作错误
问题原因
报错的核心原因是你调用Navigator.push时使用的context不属于Navigator的下层组件树:Navigator是MaterialApp内部默认提供的组件,你当前使用的context是MyApp类build方法返回的上下文,这个上下文对应的组件位置在MaterialApp的上层,Flutter从该位置向上查找父级Navigator时找不到对应实例,就会抛出这个错误。
解决方案
有两种常用的修复方式:
方案1:拆分独立首页组件
将MaterialApp的home部分代码抽成独立的StatelessWidget,新组件的build方法返回的上下文位于MaterialApp下层,可以正常获取到Navigator实例:
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const FirstRoute(), ); } } class FirstRoute extends StatelessWidget { const FirstRoute({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('First Route'), ), body: Center( child: ElevatedButton( child: const Text('Open route'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const SecondRoute()), ); }, ), ), ); } } class SecondRoute extends StatelessWidget { const SecondRoute({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Second Route"), ), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: const Text('Go back!'), ), ), ); } }
方案2:使用Builder包裹按钮
如果不想拆分组件,可以用Builder组件包裹按钮部分,Builder会生成一个位于MaterialApp下层的新上下文,使用该上下文调用Navigator即可,只需要修改MyApp的body部分代码:
body: Center( child: Builder( builder: (context) => ElevatedButton( child: const Text('Open route'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const SecondRoute()), ); }, ), ), )
内容的提问来源于stack exchange,提问作者Arghadeep Dey
相关产品推荐
相关产品推荐

