web-dev-qa-db-ja.com

PopupMenuにアイコンを表示することはできますか?

3.0で入手した新しいPopupMenuは本当に気に入っていますが、メニュー項目の横にアイコンを表示できません。以下の.xmlからメニューを拡張しています:

<item Android:id="@+id/menu_delete_product"
    Android:icon="@drawable/sym_action_add"
    Android:title="delete"
    Android:showAsAction="ifRoom|withText" />

<item Android:id="@+id/menu_modify_product"
    Android:icon="@drawable/sym_action_add"
    Android:title="modify"
    Android:showAsAction="ifRoom|withText" />

<item Android:id="@+id/menu_product_details"
    Android:icon="@drawable/sym_action_add"
    Android:title="details"
    Android:showAsAction="ifRoom|withText" />

このコードでは:

image.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        PopupMenu pop = new PopupMenu(getActivity(), v);
        pop.getMenuInflater().inflate(R.menu.shelves_details_menu, pop.getMenu());
        pop.show();
    }
});

アイコンが表示されません

45

少し冒険したい場合は、GoogleのPopupMenuのソースコードをご覧ください。独自のクラス、つまりGoogleのPopupMenuクラスと同じMyPopupMenuを作成しますが、少し変更を加えます。

PopupMenuのコンストラクターで:

public MyPopupMenu(Context context, View anchor) {
    // TODO Theme?
    mContext = context;
    mMenu = new MenuBuilder(context);
    mMenu.setCallback(this);
    mAnchor = anchor;
    mPopup = new MenuPopupHelper(context, mMenu, anchor);
    mPopup.setCallback(this);
    mPopup.setForceShowIcon(true); //ADD THIS LINE

}

setForceShowIconメソッドを使用して、強制的にアイコンを表示します。必要に応じて、パブリックメソッドを公開してこのフラグを設定することもできます。

29
Robert

Gaelan Bolgerが提供するソリューションへの貢献。 「IllegalAccessException:許可されていないフィールドへのアクセス」が発生した場合、このコードを使用します。

PopupMenu popup = new PopupMenu(mContext, view);

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

prepareMenu(popup.getMenu());
popup.show();

テキスト

68
dgtale

リフレクションを使用してアイコンを表示できました。これは最もエレガントなソリューションではないかもしれませんが、機能します。

            try {
                Class<?> classPopupMenu = Class.forName(popupMenu
                        .getClass().getName());
                Field mPopup = classPopupMenu.getDeclaredField("mPopup");
                mPopup.setAccessible(true);
                Object menuPopupHelper = mPopup.get(popupMenu);
                Class<?> classPopupHelper = Class.forName(menuPopupHelper
                        .getClass().getName());
                Method setForceIcons = classPopupHelper.getMethod(
                        "setForceShowIcon", boolean.class);
                setForceIcons.invoke(menuPopupHelper, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
18
GaBo

サブメニューモデルを使用できます。そのため、ポップアップメニューを表示するメソッドを記述する必要はありません。自動的に表示されます。ご覧ください:

menu.xml

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

<item
    Android:id="@+id/action_more"
    Android:icon="@Android:drawable/ic_menu_more"
    Android:orderInCategory="1"
    Android:showAsAction="always"
    Android:title="More">
    <menu>
        <item
            Android:id="@+id/action_one"
            Android:icon="@Android:drawable/ic_popup_sync"
            Android:title="Sync"/>
        <item
            Android:id="@+id/action_two"
            Android:icon="@Android:drawable/ic_dialog_info"
            Android:title="About"/>
    </menu>
</item>
</menu>

mainActivity.Javaで

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);   
    return true;
}

結果は次のとおりです。

Result

17

メソッドpopup.show()を使用する前に、MenuPopupHelperインスタンスを作成し、メソッドsetForceShowIcon(true)を呼び出します。

    try {
        Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup");
        mFieldPopup.setAccessible(true);
        MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu);
        mPopup.setForceShowIcon(true);
    } catch (Exception e) {

    }
11
Mao

私が見つけた最も簡単な方法は、MenuBuilderMenuPopupHelperを使用することです。

MenuBuilder menuBuilder =new MenuBuilder(this);
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.menu, menuBuilder);
MenuPopupHelper optionsMenu = new MenuPopupHelper(this, menuBuilder, view);
optionsMenu.setForceShowIcon(true);
// Set Item Click Listener
menuBuilder.setCallback(new MenuBuilder.Callback() {
    @Override
    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.opt1: // Handle option1 Click
                return true;
            case R.id.opt2: // Handle option2 Click
                return true;
            default:
                return false;
        }
    }

    @Override
    public void onMenuModeChange(MenuBuilder menu) {}
});


// Display the menu
optionsMenu.show();

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:id="@+id/opt1"
        Android:icon="@mipmap/ic_launcher"
        Android:title="option 1" />
    <item
        Android:id="@+id/opt2"
        Android:icon="@mipmap/ic_launcher"
        Android:title="option 2" />
</menu>

enter image description here

7
Ajay Sivan

MenuPopupHelper.setForceShowIcon(true)を使用して、このためのネイティブソリューションを見つけました。

private void createMenu(int menuRes, View anchor, MenuBuilder.Callback callback) {
    Context context = anchor.getContext();

    NavigationMenu navigationMenu = new NavigationMenu(context);
    navigationMenu.setCallback(callback);

    SupportMenuInflater supportMenuInflater = new SupportMenuInflater(context);
    supportMenuInflater.inflate(menuRes, navigationMenu);

    MenuPopupHelper menuPopupHelper = new MenuPopupHelper(context, navigationMenu, anchor);
    menuPopupHelper.setForceShowIcon(true);
    menuPopupHelper.show();
}

使用法

private void initMenu(View view) {
    view.findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            createMenu(R.menu.help_menu, view, new MenuBuilder.Callback() {
                @Override
                public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.id1:
                            // Do something
                            break;
                        case R.id.id2:
                            // Do something
                            break;
                        case R.id.id3:
                            // Do something
                            break;
                    }
                    return true;
                }

                @Override
                public void onMenuModeChange(MenuBuilder menu) {

                }
            });
        }
    });
}
6
Ilya Gazman

PopupMenuはアイコンを表示しません。 ActionBarを使用できます。

http://developer.Android.com/guide/topics/ui/actionbar.html

3
SpearHend

上記のソリューションのいくつかは、リフレクションハックで機能しますが、

これを共有するだけです:最近同じ問題に遭遇しましたが、よりカスタマイズされたもの(メニューにカスタムビューを追加)を作成したいので、次のライブラリを作成しました。

https://github.com/shehabic/Droppy

2
Shehabic

リフレクションの使用に沿って、MenuPopupHelperを使用する必要なしに、以下を追加できます。

    if (popup.getMenu() instanceof MenuBuilder) {
                //noinspection RestrictedApi
                ((MenuBuilder) popup.getMenu()).setOptionalIconsVisible(true);
            }

メニューを膨らませる前に

1
Nonos