49

I have an ActionBar with an action item on it. After clicking on the action item, I want to show a popup menu. I implemented this method, but I want to anchor it to the action item or to the ActionBar, not to any view from layout. How to get some kind of view to anchor it from MenuItem?

public boolean onOptionsItemSelected(MenuItem item) {
    PopupMenu popupMenu = new PopupMenu(this, ??????); // What view goes here?
    popupMenu.inflate(R.menu.counters_overflow);
    popupMenu.show();
    // ...
    return true;
}
Arnaud
  • 6,339
  • 8
  • 47
  • 64
pcu
  • 2,686
  • 4
  • 15
  • 22
  • I am doing something similar HERE!!! http://stackoverflow.com/questions/16621070/get-context-of-popupmenu-like-contextmenu – toobsco42 May 18 '13 at 16:03

5 Answers5

123

So finally I found solution. When you want to anchor popupmenu to ActionItem in ActionBar you need to find view that renders ActionItem. Simple find view with findViewById() where id is same as id of your menu item in xml.

DISPLAYING POPUP:

public boolean onOptionsItemSelected(MenuItem item) {
    // ...

    View menuItemView = findViewById(R.id.menu_overflow); // SAME ID AS MENU ID
    PopupMenu popupMenu = new PopupMenu(this, menuItemView); 
    popupMenu.inflate(R.menu.counters_overflow);
    // ...
    popupMenu.show();
    // ...
    return true;
}

MENU:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

     ....

     <item
    android:id="@+id/menu_overflow"
    android:icon="@drawable/ic_overflow"
    android:showAsAction="ifRoom"
    android:title="@string/menu_overflow"/>

     ....

</menu>

If menu item is not visible (is in overflow) it does not work. findViewById returns null so you have to check for this situation and anchor to another view.

pcu
  • 2,686
  • 4
  • 15
  • 22
2

The accepted answer wasn't working for me, so I found the problem by trial and error.

public boolean onOptionsItemSelected(MenuItem item) 
{
    View menuItemView = findViewById(item.getItemId()); 
    showPopupMenu(menuItemView)

    return true;
}

private void showPopupMenu(View anchor)
{
    PopupMenu popup = new PopupMenu(this, anchor);
    popup.getMenuInflater().inflate(R.menu.my_popup_menu, popup.getMenu());
    popup.show();
}

The key here is that, the item in onOptionsItemSelected(MenuItem item) must be shown on ActionBar. If the item is one of the items that appear when you press the 3 vertical dots on top right of ActionBar, then your app will crash.

enter image description here

Tayyab Mazhar
  • 662
  • 5
  • 11
0

plz try this ..

  @Override
public boolean onOptionsItemSelected(MenuItem item){
    String str=item.getTitle().toString(); 
    Toast.makeText(getBaseContext(), str,Toast.LENGTH_LONG). show();

    View view=findViewById(item.getItemId()); 
    switch(view.getId()){
        case Menu.FIRST:
            showPopup(view); // calling method
    }

    return super.onOptionsItemSelected(item);
}   

// custom method
private void showPopup(final View view) {
    PopupMenu popupMenu = new PopupMenu(view.getContext(), view);
    popupMenu.getMenu().add(0, 0, Menu.NONE, "Item 1");
    popupMenu.getMenu().add(0, 1, Menu.NONE, "Item 2");
    popupMenu.getMenu().add(0, 2, Menu.NONE, "Item 3");
    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(view.getContext(), item.getTitle() + "clicked", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    popupMenu.show();
}
AnAIDE
  • 21
  • 2
0

In addition to the Accepted Answer, the issue of re-inflating the popup on each call to onOptionsItemSelected() method can be simplified by doing it only once and just showing it as many times as we want.
(this works even for custom toolbar inflated via Menu Layout Inflater at runtime. Just keep in mind that the findViewById() to get the Menu item's view can return non-null value only when the view is actually present on the screen, ie, should be visible on the toolbar/actionbar.

Note: If the view is preset in the overflow menu of toolbar/actionBar there might be a chance that the view might get inflated only after the overflow menu was invoked at least once - using 3 dots?)

public class SomeActivity{
    
    private PopupMenu popup;
    .... // some code of the activity

@Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int menuItem = item.getItemId();
        switch (menuItem) {
            case R.id.tb_menu_plus:
                View menuItemView = findViewById(R.id.tb_menu_plus);
                if(popup == null) {
                    popup = new PopupMenu(this, menuItemView);
                    popup.inflate(R.menu.dropdown_popup_menu);
                }
                popup.show();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

enter image description here

mahee96
  • 162
  • 2
  • 9
-4
public boolean onOptionsItemSelected(MenuItem item) {
    final View addView = getLayoutInflater().inflate(R.layout.add, null);

            new AlertDialog.Builder(this).setTitle("Add a Word").setView(addView)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            addWord((TextView) addView.findViewById(R.id.title));
                        }
                    }).setNegativeButton("Cancel", null).show();
return (super.onOptionsItemSelected(item));
    }

get full source form here..

http://vimaltuts.com/android-tutorial-for-beginners/android-action-bar-tab-menu-example

RVG
  • 3,430
  • 4
  • 33
  • 61