PopupMenuItem 内的导航器不起作用

Nuq*_*uqo 18 dart flutter

当尝试在a 的属性Navigator内部调用时,它不起作用:onTapPopupMenuItem

PopupMenuButton(itemBuilder: (BuildContext context) {
  return [
    PopupMenuItem(
      child: Text('Edit'),
      onTap: () => Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => EditorPage())),
    ),
  ];
}),
Run Code Online (Sandbox Code Playgroud)

Nuq*_*uqo 33

弹出菜单在调用回调之前弹出自己的路由,解决此问题的一种方法是使用onSelectedPopupMenuButton自身的属性:

//---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'),
    ),
  ];
}),
Run Code Online (Sandbox Code Playgroud)


use*_*613 25

When a pop up menu is clicked, it will call pop() on the navigator to dismiss itself. So pushing an extra route would cause it to pop that route immediately, instead of dismissing itself.

Knowing this, we can change the order of the two events by slightly delaying the push() operation by 0 ms. This causes the callback to be pushed on to the event queue and thus will be executed after the menu is popped.

  PopupMenuItem(
    child: Text('Open Settings'),
    onTap: () async {
      final navigator = Navigator.of(context);
      await Future.delayed(Duration.zero);
      navigator.push(
        MaterialPageRoute(builder: (_) => SettingsPage()),
      );
    },
  )
Run Code Online (Sandbox Code Playgroud)

We can further shorten the above code to:

onTap: () => Future(
  () => Navigator.of(context).push(
    MaterialPageRoute(builder: (_) => SettingsPage()),
  ),
)
Run Code Online (Sandbox Code Playgroud)