我想单击项目菜单(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"),
),
);
}
}
我试图以这种方式在onItemMenuPress中传递上下文:
void onItemMenuPress(Choice choice, BuildContext context)
但是:
onSelected: onItemMenuPress(context)
不起作用。
这种方法都无效:
onSelected: (Choice c) { Navigator.push(context, MaterialPageRoute(builder: (context) => LogoutRoute())); }
,他的代码片段(类似于我的代码)似乎对他有用: https://github.com/duytq94/flutter-chat-demo/blob/master/lib/main.dart
我引用第235行(onSelected)和第199-205行(实际的onItemMenuPress方法)
怎么可能?我该如何保存? 谢谢
答案 0 :(得分:1)
您在这里:
MyApp <------ context
--> MaterialApp
(--> Navigator built within MaterialApp)
--> Scaffold
--> App Bar
--> ...
因此,当您使用上下文查找导航器时,将使用MyApp的上下文,该上下文不在导航器下。
因此我们可以创建一个新的Stateless或Stateful Widget子类来包含您的Scaffold
,因为其中的构建函数将指向该级别,或者我们可以使用Builder
并定义构建器回调(其中有一个指向构建器的上下文)以返回Scaffold
。
工作代码中,我们创建了新的子类-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"),
),
);
}
}
答案 1 :(得分:0)
发生这种情况是因为您的Flutter SDK和Dark SDK无法正常工作。您可以解决此问题,从而升级您的Flutter SDK。进入终端并输入
颤振升级--force
在升级完后,您的fld sdk和dark sdk将被升级,安装完成后,您会没事的。