Android ajout d'un sous-menu à un menuItem, où est addSubMenu ()?

Je veux ajouter un sous-menu dans mon OptionsMenu à un menuItem, par programmation en fonction de mes paramètres. J'ai vérifié "MenuItem" dans Android sdk et il n'y a pas de méthode addSubMenu ()!, bien que vous pouvez trouver "hasSubMenu () "et " getSubMenu".

Pensait faire cela dans 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!!!???
....

Comment créer un sous-menu dans un menuitem dans le code?

38
demandé sur ruhalde 2011-08-12 20:03:29

8 réponses

Parfois, Android weirdness est vraiment incroyable (et amusant..). Je l'ai résolu de cette façon:

A) définissez en XML un espace réservé de sous-menu comme ceci:

<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) obtenez l'élément de sous-menu dans OnCreateOptionsMenu, effacez-le et ajoutez mes éléments de sous-menu, comme ceci:

    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;
            }
}
61
répondu ruhalde 2011-08-13 00:04:29

Je sais que c'est une vieille question, mais je viens de rencontrer ce problème moi-même. La façon la plus simple de le faire, semble être de simplement spécifier l'élément lui-même en tant que sous-menu, puis Ajouter à cet élément. Par exemple:

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));
:
:
21
répondu Einar H. 2014-01-09 18:11:27

Voici une réponse complète qui s'appuie sur l'idée d'utiliser un espace réservé mais utilise principalement xml pour ajouter le sous-menu.

Si vous avez un menu comme soi-disant 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>

Créez un autre sous_menu de menu.xml qui sera utilisé dans my_menu_item:

<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>

Dans votre 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());

}

Cette solution est agréable puisque le gonfleur gère la majeure partie du travail.

16
répondu Robert 2014-10-17 20:16:13

, La meilleure façon de le faire est dans votre fichier menu xml. Vous pouvez le faire en créant un nouveau menu objet à l'intérieur d'un item:

<menu>
  <item>
    ...
    <menu>
      ...
    </menu>
    ...
  </item>
</menu>
12
répondu Phil 2011-08-12 16:28:43

Pour fournir un exemple complet de la réponse de Phil, voici mon XML complet et fonctionnel pour un menu avec deux choix, chacun étant un menu avec trois choix. J'ai l'intention d'ajouter un troisième menu au niveau supérieur ...

<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
répondu Mick 2015-07-18 23:42:52

Vous devriez envisager d'utiliser un ActionProvider à la place.

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
répondu Sibelius Seraphini 2016-09-10 15:55:36

Je voudrais simplement créer le sous-menu dans le fichier xml, et en cours d'exécution obtenir le sous-menu de l'objet menu, (en utilisant la méthode findItem(id)) et utiliser le sous-menu.setVisible (booléen) pour l'ajouter / le supprimer au moment de l'exécution.

0
répondu sorry_I_wont 2018-02-08 01:08:44
<?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
répondu Android Enthusiast 2018-03-09 20:06:59