Flutter中Navigator.push导航异常,求屏幕跳转可行方案
问题根源
你碰到的这个错误,核心原因是调用Navigator.of(context)时使用的context,属于MainApp这个StatefulWidget的上下文,它位于MaterialApp的上层。Flutter里的Navigator实例是由MaterialApp提供的,只有MaterialApp子树内的context才能找到对应的Navigator,所以用上层context调用自然会报错。
解决方案
下面提供两种可行的修复方式:
方法一:重构组件结构(推荐,更规范)
把MaterialApp从MainApp的build方法中移出,直接放在runApp里,让MainApp成为MaterialApp的子组件,这样MainApp的context就属于MaterialApp的子树,能正常访问Navigator。
修改后的主文件代码:
// ignore_for_file: no_logic_in_create_state, prefer_const_constructors, prefer_const_literals_to_create_immutables, use_super_parameters, prefer_const_constructors_in_immutables, library_private_types_in_public_api import 'package:flutter/material.dart'; import 'secondScreen.dart'; void main() { runApp( MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( scaffoldBackgroundColor: Colors.grey, appBarTheme: AppBarTheme( color: Colors.grey[50] ) ), home: MainApp(), // MainApp作为MaterialApp的子组件 ), ); } class MainApp extends StatefulWidget { MainApp ({Key ? key}) : super(key: key); @override _MainAppState createState() => _MainAppState(); } class _MainAppState extends State<MainApp> { int _currentstep = 0; @override Widget build(BuildContext context) { // 直接返回Scaffold,不再包含MaterialApp return Scaffold( appBar: AppBar( title: Text("Writing your first python code "), ), body: Center( child: Stepper( currentStep: _currentstep, onStepContinue: () => { setState(() { if(_currentstep < 100) { _currentstep ++; } }) }, onStepCancel: () => { setState(() { if (_currentstep > 0) { _currentstep --; } }) }, steps: [ Step( title: Text('Step One'), content: Text('Open Chrome') ), Step( title: Text('Step Two'), content: Text('After you open chrome search for Vscode') ), Step( title: Text('Step Three'), content: Text('Open Vscode') ), Step( title: Text('Step Four'), content: Text('Click File') ), Step( title: Text('Step Five'), content: Text('Press New Text File then click select a language') ), Step( title: Text('Step Six'), content: Text('Select Python') ), ], ), ), bottomNavigationBar: Padding( padding: EdgeInsets.all(8.0), child: ElevatedButton( onPressed: () => { Navigator.of(context).push(MaterialPageRoute(builder: (context) => SecondScreen())) }, child: Text('Done'), ), ), ); } }
方法二:用Builder组件包裹按钮(快速修复)
如果不想调整整体结构,可以用Builder组件包裹ElevatedButton,Builder会提供一个属于MaterialApp子树的context,用这个context调用Navigator即可。
修改后的bottomNavigationBar部分代码:
bottomNavigationBar: Padding( padding: EdgeInsets.all(8.0), child: Builder( // 新增Builder组件 builder: (context) => ElevatedButton( onPressed: () => { Navigator.of(context).push(MaterialPageRoute(builder: (context) => SecondScreen())) }, child: Text('Done'), ), ), ),
内容的提问来源于stack exchange,提问作者laith maree
相关产品推荐
相关产品推荐

