Anchoring a PopupMenu to Navigationview menu items

1.4k views Asked by At

Since this question and its answer didn't show up anywhere, thought I might as well contribute a little for once by sharing the way I found.

So I had this issue with anchoring a PopupMenu object to a NavigationView menu since I couldn't get any items out of it in the form of a view:

//onCreate:
     NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        drawerMenu = navigationView.getMenu();


//onNavigationItemSelected(MenuItem menuItem):
     switch (menuItem.getItemId()) {
                case R.id.menubutton_submenuButton:
                    //the following line is merely how I'd imagine it should be
                    PopupMenu popupMenu = new PopupMenu(this, drawerMenu.findItem(R.id.menubutton_submenuButton));
                    popupMenu.getMenuInflater().inflate(R.menu.sub_menu, popupMenu.getMenu());
                    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            //handle the inflated menu's buttons here
                            return true;
                        }
                    });
                    popupMenu.show();
                    break;
    }

So then, the problem is basically where

drawerMenu.findItem(R.id.menubutton_submenuButton));

isn't a View of any sort, which leaves the PopupMenu with nothing to anchor to.

1

There are 1 answers

0
MrGuy On BEST ANSWER

So I figured you can just create an empty view inside the menu item as follows: create a layout xml file including only the following:

<?xml version="1.0" encoding="utf-8"?>
<View
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    />

lets call it "view_empty".

Now the menu item should have that empty view layout included inside of it by adding the following line to its item: app:actionLayout="@layout/drawer_empty"
My item looks as follows:

<item
                android:id="@+id/menubutton_submenuButton"
                android:title="example menu item"
                app:actionLayout="@layout/view_empty"/>

Now then, all that's left is just using it:

//onNavigationItemSelected(MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.menubutton_submenuButton:
                MenuItem item = drawerMenu.findItem(R.id.menubutton_submenuButton);
                PopupMenu popupMenu = new PopupMenu(this, MenuItemCompat.getActionView(item));
                popupMenu.getMenuInflater().inflate(R.menu.sub_menu, popupMenu.getMenu());
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        //handle the inflated menu's buttons here
                        return true;
                    }
                });
                popupMenu.show();
                break;

What'd happen now is that the PopupMenu would anchor itself to an invisible view inside the menuItem, thus making it look like the container menuItem is the anchor point.