fin*_*tis 6 dart flutter flutter-navigation
我曾经使用 IconButton 的onpressed从我的 AppBar 导航到设置页面,这是有效的。现在我试图从 PopupMenuItem 的onTap触发导航,但页面不导航。两个小部件都位于同一层次结构中,我无法找出不同行为的原因。不会抛出任何错误。
这是我的 appBar 的代码,其中包含操作:
Widget build(BuildContext ctx) {
return Container(
child: Scaffold(
appBar: AppBar(
title: const Text('MyApp'),
actions: [
PopupMenuButton(
itemBuilder: (context) => [
// THE NAVIGATION IN onTap DOES NOT WORK
PopupMenuItem(
child: Text(AppLocalizations.of(context).settings),
onTap: () => _openSettings(ctx),
),
],
icon: Icon(
Icons.settings,
),
),
// THIS WORKS
IconButton(onPressed: () => _openSettings(ctx),
icon: Icon(Icons.settings))
],
),
body: Text("")
),
);
}
Run Code Online (Sandbox Code Playgroud)
这里的导航调用只能在 IconButton 的onpressed内部工作。我可以确认该函数在这两种情况下都被触发:
Future<void> _openSettings(BuildContext ctx) async {
print('settings');
await Navigator.push(
ctx, MaterialPageRoute(builder: (ctx) => SettingsPage()));
print('settings completed');
}
Run Code Online (Sandbox Code Playgroud)
我将不胜感激任何帮助!
解决方法: 我还没有发现onTap导航的问题是什么,但现在我只是使用onSelected,它会产生相同的用户体验并且有效:
Widget build(BuildContext ctx) {
return Container(
child: Scaffold(
appBar: AppBar(
title: const Text('MyApp'),
actions: [
PopupMenuButton(
onSelected: (result){
switch(result){
case 0: _openSettings(); break;
case 1: _signOut(); break;
}
},
itemBuilder: (context) => [
PopupMenuItem(
child: Text(AppLocalizations.of(context).settings),
value: 0
),
PopupMenuItem(
child: Text(AppLocalizations.of(context).logout),
value: 1
)
],
icon: Icon(
Icons.settings,
),
)
],
)
)
);
}
Run Code Online (Sandbox Code Playgroud)
我也遇到了这个问题并解决如下:
onTap或赋予它的值null。value其次,为中的参数赋值PopupMenuItem。您可以提供任何类型,例如int或String或任何您想要的类型,因为值是动态的。onSelected给PopupMenuButton.onSelected功能内,您可以选择按下任何菜单项时要执行的操作。在你的情况下,你的代码应该是这样的
PopupMenuButton(
itemBuilder: (context) => [
PopupMenuItem(
child: Text(...),
value: 'settings',
),
],
onSelected: (value){
if(value == 'settings'){
_openSettings(ctx);
}
},
),
Run Code Online (Sandbox Code Playgroud)
您需要使用 调用 future 函数()=>,并传递Build Context该函数以了解要从哪个上下文导航。
所以你的按钮会像这样改变:
IconButton(onPressed:()=> _openSettings(context), icon: Icon(Icons.settings))
Run Code Online (Sandbox Code Playgroud)
你的函数应该是这样的:
Future<void> _openSettings(BuildContext ctx) async {
print('settings');
await Navigator.push(
ctx, MaterialPageRoute(builder: (context) => SettingPage()));
print('settings completed');
}
Run Code Online (Sandbox Code Playgroud)
class PlayGround extends StatefulWidget {
const PlayGround({Key? key}) : super(key: key);
@override
_PlayGroundState createState() => _PlayGroundState();
}
class _PlayGroundState extends State<PlayGround> {
final _title =
TextEditingController.fromValue(TextEditingValue(text: 'initialTitle'));
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('MyApp'),
actions: [
PopupMenuButton<int>(
itemBuilder: (context) => [
PopupMenuItem(
child: Text(AppLocalizations.of(context).settings),
onTap: () {},
),
PopupMenuItem(
child: Text(AppLocalizations.of(context).logout),
onTap: () {},
)
],
icon: Icon(
Icons.settings,
),
),
IconButton(
onPressed: () => _openSettings(context),
icon: Icon(Icons.settings))
],
),
body: Container());
}
Future<void> _openSettings(BuildContext ctx) async {
print('settings');
await Navigator.push(
ctx, MaterialPageRoute(builder: (context) => SettingPage()));
print('settings completed');
}
}
class SettingPage extends StatelessWidget {
const SettingPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4277 次 |
| 最近记录: |