[英]Flutter can't change route because undefined name context with PopupMenuButton how to solve?
I want to click an item menu (PopupMenuItem) and go to another route using Navigator.push but context is undefined inside the method.我想单击一个项目菜单 (PopupMenuItem) 并使用 Navigator.push 转到另一条路线,但该方法内部未定义上下文。
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:我试图以这种方式在 onItemMenuPress 中传递上下文:
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我正在关注本教程: 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并且有一段他的代码(类似于我的)似乎对他有用: 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)我指的是第 235 行(onSelected)和第 199-205 行(实际的 onItemMenuPress 方法)
How is it possible?这怎么可能? How can I salve?我该如何解救? Thanks谢谢
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.因此,当您使用上下文来查找导航器时,您正在使用不在导航器下的 MyApp 的上下文。 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
.所以我们可以创建一个新的 Stateless 或 Stateful Widget 子类来包含您的Scaffold
,因为它们中的构建函数将指向该级别,或者我们可以使用Builder
并定义构建器回调(它有一个指向 Builder 的上下文) 返回Scaffold
。
Working Code we created new subclass - HomeScreen
:我们创建了新子类的工作代码 - 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"),
),
);
}
}
It happens because your flutter SDK and dark SDK is not working properly.发生这种情况是因为您的 flutter SDK 和 dark SDK 无法正常工作。 you can solve this issues upgrading your flutter sdk.你可以通过升级你的 flutter sdk 来解决这个问题。 go to the terminal and type转到终端并输入
flutter upgrade --force颤振升级--force
after that your fluter sdk and dark sdk will be upgrade, after the installation complete you will be fine.之后你的fluter sdk和dark sdk将升级,安装完成后你会没事的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.