Flutter can't change route because undefined name context with PopupMenuButton how to solve?
Here you have :
MyApp <------ context
--> MaterialApp
(--> Navigator built within MaterialApp)
--> Scaffold
--> App Bar
--> ...
So when you're using the context to find the Navigator, you're using a context for the MyApp which isn't under the navigator.
so we can either make a new Stateless or Stateful Widget subclass to contain your Scaffold
, as the build function within those will point at that level instead, or we can use a Builder
and define the builder callback (which has a context pointing at the Builder) to return the Scaffold
.
Working Code we created new subclass - HomeScreen
:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = 'MyTitle';
return MaterialApp(
title: title,
home: HomeScreen(title),
);
}
}
class HomeScreen extends StatelessWidget {
final String title;
HomeScreen(this.title);
final List<Choice> choices = const <Choice>[
const Choice(title: 'Settings', icon: Icons.settings),
const Choice(title: 'Log out', icon: Icons.exit_to_app),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
actions: <Widget>[
PopupMenuButton<Choice>(
onSelected: (val) => onItemMenuPress(val, context),
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Row(
children: <Widget>[
Icon(
choice.icon,
),
Container(
width: 10.0,
),
Text(
choice.title,
),
],
));
}).toList();
},
),
],
),
body: Text("Hello world"));
}
void onItemMenuPress(Choice choice, BuildContext context) {
if (choice.title == 'Log out') {
print("Logout");
Navigator.push(
context, MaterialPageRoute(builder: (context) => LogoutRoute()));
}
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
class LogoutRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Logout"),
),
body: Center(
child: Text("Screen"),
),
);
}
}
Francesco Romano
Updated on December 09, 2022Comments
-
Francesco Romano over 1 year
I want to click an item menu (PopupMenuItem) and go to another route using Navigator.push but context is undefined inside the method.
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { final List<Choice> choices = const <Choice>[ const Choice(title: 'Settings', icon: Icons.settings), const Choice(title: 'Log out', icon: Icons.exit_to_app), ]; @override Widget build(BuildContext context) { final title = 'MyTitle'; return MaterialApp( title: title, home: Scaffold( appBar: AppBar( title: Text(title), actions: <Widget>[ PopupMenuButton<Choice>( onSelected: onItemMenuPress, itemBuilder: (BuildContext context) { return choices.map((Choice choice) { return PopupMenuItem<Choice>( value: choice, child: Row( children: <Widget>[ Icon( choice.icon, ), Container( width: 10.0, ), Text( choice.title, ), ], )); }).toList(); }, ), ], ), body: Text("Hello world") ), ); } void onItemMenuPress(Choice choice) { if (choice.title == 'Log out') { print("Logout"); Navigator.push(context, MaterialPageRoute(builder: (context) => LogoutRoute())); } } } class Choice { const Choice({this.title, this.icon}); final String title; final IconData icon; } class LogoutRoute extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Logout"), ), body: Center( child: Text("Screen"), ), ); } }
I have tried to pass a context in onItemMenuPress in this way:
void onItemMenuPress(Choice choice, BuildContext context)
but:
onSelected: onItemMenuPress(context)
is not working.
Neither this approach works:
onSelected: (Choice c) { Navigator.push(context, MaterialPageRoute(builder: (context) => LogoutRoute())); }
I was following this tutorial: https://medium.com/flutter-community/building-a-chat-app-with-flutter-and-firebase-from-scratch-9eaa7f41782e
and there is a snippet of his code (similar to mine) that seems to work for him: https://github.com/duytq94/flutter-chat-demo/blob/master/lib/main.dart
I refer to line 235 (onSelected) and lines 199-205 (actual onItemMenuPress method)
How is it possible? How can I salve? Thanks