web-dev-qa-db-ja.com

Android menuItemへのサブメニューの追加、addSubMenu()はどこにありますか?

OptionsMenu内のサブメニューをmenuItemに、パラメーターに従ってプログラムで追加したい。 Android sdkで "MenuItem"をチェックし、addSubMenu()メソッドはありませんが、 "hasSubMenu()"と "getSubMenu"を見つけることができます。

OnCreateOptionsMenuでこれを行うことを考えていました:

public boolean onCreateOptionsMenu(Menu menu) {

    MenuItem mi = menu.getItem(MYITEMID);  // << this is defined in my XML optionsMenu
    SubMenu subm = mi.addSubMenu(0,1,0,"Map 1"); // no addSubMenu() method!!!???
....

コード内のメニュー項目内にサブメニューを作成するにはどうすればよいですか?

40
ruhalde

時々Android奇妙さは本当に驚くべき(そして面白い..)。私はこの方法でそれを解決した:

a)XMLで次のようなサブメニュープレースホルダーを定義します。

<item Android:visible="true" Android:id="@+id/m_area"
   Android:titleCondensed="Areas"
   Android:title="Areas"
   Android:icon="@drawable/restaur"
   Android:enabled="true"> 
   <menu>
    <item Android:id="@+id/item1" Android:title="Placeholder"></item>
   </menu>
</item>

b)OnCreateOptionsMenuでサブメニュー項目を取得し、クリアして、次のようにサブメニュー項目を追加します。

    public boolean onCreateOptionsMenu(Menu menu) { 
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.mapoptions, menu);

            int idx=0;
            subm = menu.getItem(MYITEM_INDEX).getSubMenu(); // get my MenuItem with placeholder submenu
            subm.clear(); // delete place holder

            while(true)
            {
                anarea = m_areas.GetArea(idx); // get a new area, return null if no more areas
                if(anarea == null)
                    break;
                subm.add(0, SUBAREASID+idx, idx, anarea.GetName()); // id is idx+ my constant
                ++idx;
            }
}
65
ruhalde

これは古い質問ですが、自分でこの問題に出くわしました。これを行う最も簡単な方法は、アイテム自体をサブメニューとして指定し、このアイテムに追加することです。例えば。:

menu.add(groupId, MENU_VIEW, Menu.NONE, getText(R.string.menu_view));
menu.add(groupId, MENU_EDIT, Menu.NONE, getText(R.string.menu_edit));
SubMenu sub=menu.addSubMenu(groupId, MENU_SORT, Menu.NONE, getText(R.string.menu_sort));
sub.add(groupId, MENU_SORT_BY_NAME, Menu.NONE, getText(R.string.menu_sort_by_name));
sub.add(groupId, MENU_SORT_BY_ADDRESS, Menu.NONE, getText(R.string.menu_sort_by_address));
:
:
25
Einar H.

プレースホルダーを使用するという考えに基づいて構築された完全な回答を次に示しますが、ほとんどがxmlを使用してサブメニューを追加します。

Main_menu.xmlと呼ばれるようなメニューがある場合:

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:title="My Menu"
    Android:id="@+id/my_menu_item">
    <!-- A empty SubMenu -->
    <menu></menu>
</item>
</menu>

My_menu_itemで使用される別のメニューsub_menu.xmlを作成します。

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
  <item Android:title="SubMenu One"
    Android:id="@+id/submenu_one" />
  <item Android:title="SubMenu Two"
    Android:id="@+id/submenu_two" />
  <item Android:title="SubMenu Three"
    Android:id="@+id/submenu_three" />
</menu>

OnCreateOptionsMenuで:

public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate your main_menu into the menu
   getMenuInflater().inflate(R.menu.main_menu, menu);

   // Find the menuItem to add your SubMenu
   MenuItem myMenuItem = menu.findItem(R.id.my_menu_item);

   // Inflating the sub_menu menu this way, will add its menu items 
   // to the empty SubMenu you created in the xml
   getMenuInflater().inflate(R.menu.sub_menu, myMenuItem.getSubMenu());

}

インフレータがほとんどの作業を処理するため、このソリューションは素晴らしいです。

19
Robert

これを行う最良の方法は、xmlメニューファイルを使用することです。これを行うには、menu内に新しいitemオブジェクトを作成します。

<menu>
  <item>
    ...
    <menu>
      ...
    </menu>
    ...
  </item>
</menu>
16
Phil
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@+id/menu1" Android:alphabeticShortcut="a"
    Android:title="Menu No. 1" Android:orderInCategory="1" />
<item Android:id="@+id/menu2" Android:alphabeticShortcut="b"
    Android:title="Menu No. 2" Android:orderInCategory="2">
    <menu >
    <group Android:id="@+id/group2" Android:checkableBehavior="single">
        <item Android:id="@+id/submenu1" Android:title="SubMenu No. 1" />
        <item Android:id="@+id/submenu2" Android:title="SubMenu No. 2" />
    </group>   
    </menu>
</item>
0

Xmlファイルでサブメニューを作成し、実行時にメニューオブジェクトからサブメニューを取得し(findItem(id)メソッドを使用)、実行時にsubmenu.setVisible(boolean)を使用して追加/削除します。

0
sorry_I_wont

Philの答えの包括的な例を提供するために、2つの選択肢を持つメニューの完全な作業XMLを以下に示します。それぞれの選択肢は3つの選択肢を持つメニューです。最上位に3番目のメニューを追加する予定です...

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

    <item Android:id="@+id/Examine"
        Android:title="@string/Examine"
        HTMLCode:showAsAction="always">

        <menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
            xmlns:HTMLCode="http://schemas.Android.com/apk/res-auto" >
            <item Android:id="@+id/load"
                Android:title="@string/load"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item Android:id="@+id/findfirst"
                Android:title="@string/findfirst"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item Android:id="@+id/findnext"
                Android:title="@string/FindNext"
                HTMLCode:showAsAction="ifRoom|withText" />
        </menu>
    </item>

    <item Android:id="@+id/Redirect"
        Android:title="@string/Redirect"
        HTMLCode:showAsAction="ifRoom|withText">

        <menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
            xmlns:HTMLCode="http://schemas.Android.com/apk/res-auto" >
            <item Android:id="@+id/getRedirect"
                Android:title="@string/getRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item Android:id="@+id/toggleRedirect"
                Android:title="@string/toggleRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />

            <item Android:id="@+id/copyRedirect"
                Android:title="@string/copyRedirect"
                HTMLCode:showAsAction="ifRoom|withText" />
        </menu>
    </item>
</menu>
0
Mick

代わりにActionProviderの使用を検討する必要があります。

public class MyActionProvider extends ActionProvider {

    private Context mContext;

    public MyActionProvider(Context context) {
        super(context);

        mContext = context;
    }

    @Override
    public View onCreateActionView() {
        //LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        return null;
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        super.onPrepareSubMenu(subMenu);

        subMenu.clear();

        subMenu.add("menu 1");
        subMenu.add("menu 2");
        subMenu.add("menu 3");
    }

    @Override
    public boolean hasSubMenu() {
        return true;
    }

    @Override
    public boolean onPerformDefaultAction() {
        return super.onPerformDefaultAction();
    }
}
0