20

How can we implement use of onTap or onPressed in PopupMenuItem

Here is my code:

actions: <Widget>[
  PopupMenuButton(
    icon: Icon(Icons.settings),
    itemBuilder: (context) => [
      PopupMenuItem(
        child: Text("Settings"),
      ),
      PopupMenuItem(
        child: Text("Flutter.io"),
      ),
      PopupMenuItem(
        child: Text("Google.com"),
      ),
    ],
  ),
]

I want to navigate to SettingPage() on tapping or clicking Settings PopupMenuItem.
I am getting this error even after following a solution mentioned below and even after importing dart:js

Error: Not found: 'dart:js'
import 'dart:js';

Here are my dependencies:

import 'package:bfdi_app/Profile/editProfile.dart';
import 'package:bfdi_app/models/user.dart';
import 'package:bfdi_app/services/collection.dart';
import 'package:bfdi_app/settings.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'dart:js';

Himanshu Sharma
  • 984
  • 2
  • 15
  • 40

9 Answers9

43

Just add this to your PopupMenuButton:

onSelected: (result) {
    if (result == 0) {
        Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => SettingPage()),
        );
    }
},

And change your setting button to:

PopupMenuItem(
    child: Text("Settings"),
    value: 0,
),
no_fate
  • 1,625
  • 14
  • 22
10

There is a property called onSelected, you should use it, it handles onTap event.

PopupMenuButton(
  icon: Icon(Icons.settings),
  onSelected: (newValue) { // add this property
    setState(() {
      _value = newValue; // it gives the value which is selected
    });
  },
  itemBuilder: (context) => [
    PopupMenuItem(
      child: Text("Settings"),
      value: 0,
    ),
    PopupMenuItem(
      child: Text("Flutter.io"),
      value: 1,
    ),
    PopupMenuItem(
      child: Text("Google.com"),
      value: 2,
    ),
  ],
)
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
7

I faced similar issues while navigating the screen using pop up menu button and I solve the issues by putting this method inside the onTap callback of PopupMenuItem:

    onTap: (){
WidgetsBinding.instance!.addPostFrameCallback((_) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) {
                            return ScreenName();
                          },
                        ),
                      );
                    });
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Prakash Basnet
  • 121
  • 2
  • 2
2

There is now an onTap() for PopupMenuItem.

      PopupMenuButton(
        itemBuilder: (context) => [
          PopupMenuItem(
            child: Text("tap me"),
            onTap: () => print("TAP"),
          )
        ],
      ),
falconforce
  • 140
  • 1
  • 5
1

-Edited based on comment-

That's it :

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var items = [{'name':'Settings','value':0}, {'name':'Flutter.io','value':1}, {'name':'Google.com',,'value':2}];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: PopupMenuButton(
              onSelected: (x) {
           if(x==0){
                Navigator.push(
                     context,
                     MaterialPageRoute(builder: (context) => SettingPage()), );}
              },
              icon: Icon(Icons.settings),
              itemBuilder: (context) => items
                  .map<PopupMenuItem>((element) => PopupMenuItem(
                        child: Text(element['name]),
                        value: element['value'],
                      ))
                  .toList()),


    ));
  }
}

Mohamed Gaber
  • 1,625
  • 1
  • 10
  • 22
1

Callable value.

PopupMenuButton(
  icon: Icon(Icons.settings),
  onSelected: (value) {
    value();
  },
  itemBuilder: (context) => [
    PopupMenuItem(
      child: Text('Settings'),
      value: () {
        debugPrint('open Settings');
      },
    ),
    PopupMenuItem(
      child: Text('Flutter.io'),
      value: () {
        debugPrint('goto Flutter.io');
      },
    ),
  ],
)
ytyng
  • 575
  • 6
  • 8
  • This is a very clever solution. It avoids having to create a separate switch-case handler function to execute an action after a value was selected – Mohamad Abdel Rida Nov 17 '22 at 22:27
0

Use inheritance when showing popup with showMenu(...)

class PopupItem<T> extends PopupMenuItem<T> {

  final Function() onTap;

  PopupItem({this.onTap, Widget child, Key key})
      : super(child: child, key: key);

  @override
  _PopupItemState<T> createState() => _PopupItemState<T>();
}

class _PopupItemState<T> extends PopupMenuItemState<T, PopupItem<T>> {
  @override
  void handleTap() {
    widget.onTap?.call();
    super.handleTap();
  }
}

Usage:

  Widget _itemDelete() => PopupItem(
        onTap: () {
          // Handle tap here
        },
        child: Text(...)
      );
Nickolay Savchenko
  • 1,474
  • 16
  • 28
0
onTap: (){

                  WidgetsBinding.instance!.addPostFrameCallback((_) {

                      Navigator.push(

                        context,
                        MaterialPageRoute(

                          builder: (context)=>Page())): 

                          },
                        ),
                      );
                    });
}
vimuth
  • 5,064
  • 33
  • 79
  • 116
Ofsam
  • 1
  • 1
0

PopupMenuButton ( padding: EdgeInsets.zero, icon:const Icon(Icons.keyboard_arrow_down_outlined,color: Color.fromRGBO(34, 178, 232, 1)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(15.0)) ),

                  onSelected: (x){
                    if (x=="Edit User") {
                      Get.to(EditUserPage());
                    }
                    else if(x=="Login History"){
                      Get.to(EditUserPage());
                    }
                    else if(x=="Change Password"){
                      Get.to(EditUserPage());
                    }
                    else if(x=="Deactivate User"){
                      Get.to(EditUserPage());
                    }
                  },
                  itemBuilder: (BuildContext context) => <PopupMenuEntry >[
                    PopupMenuItem (
                      onTap: (){},
                      value:"Edit User",
                      child:  Row(
                        children: [
                          svgWedget(url:"assets/svg/edit.svg"),
                          SizedBox(width: 10,),
                          Text("Edit User"),
                        ],
                      ),
                    ),
                    PopupMenuItem (
                      onTap: ( )async{},
                      value:"Login History",
                      child:  Row(
                        children: [
                          svgWedget(url:"assets/svg/calendar.svg"),
                          SizedBox(width: 10,),
                          Text("Login History"),
                        ],
                      ),
                    ),
                    PopupMenuItem (
                      onTap: ()async{},
                      value:"Change Password",
                      child:  Row(
                        children: [
                          SvgPicture.asset("assets/svg/lock.svg",color: Color.fromRGBO(195, 172, 255, 1),),
                          SizedBox(width: 10,),
                          Text("Change Password"),
                        ],
                      ),
                    ),
                    PopupMenuItem (
                      onTap: ()async{},
                      value:"Deactivate User",
                      child:  Row(
                        children: [
                          svgWedget(url:"assets/svg/trash.svg"),
                          SizedBox(width: 10,),
                          Text("Deactivate User"),
                        ],
                      ),
                    ),
                  ]
              ),
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 09 '22 at 04:11