弹出菜单项内的导航器无法工作

18
当尝试在 PopupMenuItemonTap 属性内调用 Navigator 时,它不起作用。
PopupMenuButton(itemBuilder: (BuildContext context) {
  return [
    PopupMenuItem(
      child: Text('Edit'),
      onTap: () => Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => EditorPage())),
    ),
  ];
}),
2个回答

33

弹出式菜单在调用回调之前弹出了自己的路由,解决方法是使用PopupMenuButton本身的onSelected属性:

//---add onSelected to your PopupMenuButton
PopupMenuButton(onSelected: (result) {
  if (result == 0) {
    Navigator.of(context)
        .push(MaterialPageRoute(builder: (context) => EditorPage()));
  }
}, itemBuilder: (BuildContext context) {
  return [
    PopupMenuItem(
      value: 0, //---add this line
      child: Text('Edit'),
    ),
  ];
}),

25

当单击弹出式菜单时,它会在导航器上调用pop()以关闭自身。因此,推送额外的路由将立即导致该路由被弹出,而不是关闭自身。

了解这一点后,我们可以通过稍微延迟push()操作0 ms来改变两个事件的顺序。这将导致回调被推送到事件队列中,因此在菜单关闭后执行。

  PopupMenuItem(
    child: Text('Open Settings'),
    onTap: () async {
      final navigator = Navigator.of(context);
      await Future.delayed(Duration.zero);
      navigator.push(
        MaterialPageRoute(builder: (_) => SettingsPage()),
      );
    },
  )
我们可以进一步缩短上述代码为:
onTap: () => Future(
  () => Navigator.of(context).push(
    MaterialPageRoute(builder: (_) => SettingsPage()),
  ),
)

这真是奇怪的行为。我永远也想不到。谢谢! - Chris
卡在这里有一段时间了。经常错过 event.preventDefault()。顺便说一下,好的解决方案!谢谢! - Tariqul Islam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接