sd2001
sd2001

Reputation: 31

PopupMenu with icons displayed incorrectly - Android Studio

In higher SDKs like 33 the PopupMenu with Icons is displayed incorrectly: Wrong PopupMenu with Icons

I don't know what is wrong.

I created it like this:

//init the wrapper with style
Context wrapper = new ContextThemeWrapper(anchor.getContext(), R.style.MyPopupStyle);

//init the popup
PopupMenu popup = new PopupMenu(wrapper, anchor);

/*  The below code in try catch is responsible to display icons*/
if (isWithIcons) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        popup.setForceShowIcon(true);
    } else {
        try {
            Field[] fields = popup.getClass().getDeclaredFields();
            for (Field field : fields) {
                if ("mPopup".equals(field.getName())) {
                    field.setAccessible(true);
                    Object menuPopupHelper = field.get(popup);
                    assert menuPopupHelper != null;
                    Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
                    Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
                    setForceIcons.invoke(menuPopupHelper, true);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//inflate menu
popup.getMenuInflater().inflate(menu, popup.getMenu());

popup.show();

I tried with SDK 23 and there it is displayed correctly: Correct PopupMenu with Icons

Upvotes: 1

Views: 376

Answers (1)

sd2001
sd2001

Reputation: 31

The following post did work for me: https://stackoverflow.com/a/41666520/18030070

To center the image vertically, I used this class: https://stackoverflow.com/a/38788432/18030070

/**
 * method responsible to show popup menu
 *
 * @param anchor      is a view where the popup will be shown
 * @param isWithIcons flag to check if icons to be shown or not
 * @param menu        menu items for popup menu
 */
public static PopupMenu showPopupMenu(View anchor, boolean isWithIcons, @MenuRes int menu) {
    //init the wrapper with style
    Context wrapper = new ContextThemeWrapper(anchor.getContext(), R.style.MyPopupStyle);

    //init the popup
    PopupMenu popupMenu = new PopupMenu(wrapper, anchor);

    //inflate menu
    popupMenu.getMenuInflater().inflate(menu, popupMenu.getMenu());

    /*  The below code in try catch is responsible to display icons*/
    if (isWithIcons) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            insertMenuItemIcons(anchor.getContext(), popupMenu);

        } else {
            try {
                Field[] fields = popupMenu.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if ("mPopup".equals(field.getName())) {
                        field.setAccessible(true);
                        Object menuPopupHelper = field.get(popupMenu);
                        assert menuPopupHelper != null;
                        Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
                        Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
                        setForceIcons.invoke(menuPopupHelper, true);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    return popupMenu;
}

Upvotes: 2

Related Questions