(Popup)Menus

Various snippets for creating overflow menus, popup menus, and how to style them.

Defining a menu

Whether popup-, context-, or navigation menu: define it in the resources:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >  

    <item  
        android:id="@+id/action_one"
        android:title="@string/menu_one"/>  

    <item  
        android:id="@+id/action_two"
        android:title="@string/menu_two"/>

</menu>

Overflow menu

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.menu, menu);
  return true;
}

anchorView is the view that triggers the popup. The popup should show right around it.

PopupMenu popup = new PopupMenu(MainActivity.this, anchorView);
popup.getMenuInflater()
  .inflate(R.menu.popup_menu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
  public boolean onMenuItemClick(MenuItem item) {
    // ...
    return true;
  }
});
popup.show();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(layoutId, null, false);
mPopupWindow = new PopupWindow(context);
mPopupWindow.setFocusable(true);
mPopupWindow.setWindowLayoutMode(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
mPopupWindow.setContentView(view);
// If the layout contains a background, disable the default one:
mPopupWindow.setBackgroundDrawable(null);

If your layout contains a NavigationView, handle events like so:

NavigationView navView = view.findViewById(R.id.navigation_view);
navView.setNavigationItemSelectedListener(menuItem -> {
	    mPopupWindow.dismiss();
    	mListener.onNavigationItemSelected(menuItem);
    	return true;
	});

If you’re using the FontUtil, use it to apply the typeface to the menu:

FontUtil.setTypefaceOnMenu(navView.getMenu());

Then you can show it anchored to anchorView or at a specific location:

mPopupWindow.showAsDropDown(anchorView, 0, 0);
// or
mPopupWindow.showAtLocation(
    parentView,
    Gravity.CENTER_VERTICAL,
    xOffset,
    yOffset);

Styling a menu

To add icons, colors, typefaces or other styling to a menu, use Spans. The FontUtil class has the implementations required. It boils down to:

public static void setTypefaceOnMenu(Menu menu) {
    // Apply styling to overflow/popup/navigation menu items
    for (int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        // Implement setStylingOptions to create a Span with
        // drawables or other styling applied to a String:
        item.setTitle(setStylingOptions(item.getTitle().toString()));
    }
}