web-dev-qa-db-fra.com

Comment ajouter des éléments de sous-menu à l'action ActionBar dans le code?

Via xml, je peux ajouter des éléments de sous-menu à mon action dans le ActionBar.

enter image description here

main_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:id="@+id/menu_new_form"
          Android:icon="@drawable/ic_new_form"
          Android:title="@string/menu_new_form"
          Android:showAsAction="ifRoom|withText">
        <menu>
            <item Android:id="@+id/form1"
                  Android:icon="@drawable/attachment"
                  Android:title="Form 1"
                  Android:onClick="onSort" />
            <item Android:id="@+id/form2"
                  Android:icon="@drawable/attachment"
                  Android:title="Form 2"
                  Android:onClick="onSort" />
        </menu>
    </item>
</menu>

Mais comment puis-je ajouter ces sous-éléments via Java code ? Il ne fonctionne pas comme ci-dessous, les sous-éléments sont ajoutés à la mauvaise action (et le dessin ne s'affiche pas non plus), le très à droite, pas le bouton "Nouveau formulaire":

enter image description here

main_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:id="@+id/menu_new_form"
          Android:icon="@drawable/ic_new_form"
          Android:title="@string/menu_new_form"
          Android:showAsAction="ifRoom|withText">
    </item>
</menu>

Code Java:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    Log.d("MainMenu", ",menu title0: " + menu.getItem(0).getTitle()); 
    // returns "New Form"

    menu.addSubMenu(0, Menu.NONE, 1, "Form 1").setIcon(R.drawable.attachment);
    menu.addSubMenu(0, Menu.NONE, 2, "Form 2").setIcon(R.drawable.attachment);
    return true;
}

Est-il possible d’y parvenir en ajoutant des éléments de sous-menu via Java Code au lieu de XML, sans à l’aide d’un PopupMenu ( http://developer.Android.com/guide/topics/ui/menus.html#PopupMen )?

Mise à jour (Solution):

Mon dernier extrait de code que j'ai utilisé pour remplir le sous-menu dynamiquement, à la suite de la réponse d'adamp:

// menu options
private static final int MENU_PREFERENCES = Menu.FIRST;
private static final int MENU_LOGOUT = 2;

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    super.onCreateOptionsMenu(menu);

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    menu.add(0, MENU_PREFERENCES, 0, getString(R.string.general_preferences)).setIcon(
            Android.R.drawable.ic_menu_preferences);

    // load all available form templates
    Cursor c = managedQuery(FormsProviderAPI.FormsColumns.CONTENT_URI, null, null, null, null);
    try {
        int ixDisplayName = c.getColumnIndex(FormsProviderAPI.FormsColumns.DISPLAY_NAME);
        int ixId = c.getColumnIndex(FormsProviderAPI.FormsColumns._ID);
        int cnt = 0;
        while (c.moveToNext()) {
            cnt++;
            Log.d("ID: ", "ID: "+ c.getInt(ixId));  // misusing the group id for the form id
            menu.getItem(1).getSubMenu().addSubMenu(c.getInt(ixId), Menu.NONE, cnt, c.getString(ixDisplayName)).setIcon(R.drawable.attachment_dark);
        }
    } catch (Exception e) {
        Log.e(TAG, "Error init form templates list.", e);
    }

    return true;
}
62
Mathias Conradt

Oui il y a.

La méthode addSubMenu renvoie un objet SubMenu . Un SubMenu est aussi un Menu , de sorte que vous pouvez appeler add pour ajouter des éléments au sous-menu plutôt qu'au menu parent. Votre code ci-dessus crée deux sous-menus différents pour les formulaires 1 et 2 plutôt que deux éléments dans un seul sous-menu Nouveau formulaire.

Exemple:

SubMenu submenu = menu.addSubMenu(0, Menu.NONE, 1, "New Form").setIcon(R.drawable.ic_new_form);
submenu.add("Form 1").setIcon(R.drawable.attachment);
35
adamp

Ajouter un ActionProvider est peut-être plus facile. Vous pouvez essayer comme expliqué ici

2
Filippo Mazza

Vous devriez envisager d'utiliser un ActionProvider

exemple: https://Gist.github.com/sibelius/7ca0b757492ff6740dec

Menu avec élément de fournisseur d'action

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

    <item Android:id="@+id/action_companies"
        Android:icon="@drawable/ic_list"
        Android:title="@string/action_companies"
        app:actionProviderClass="com.example.MyActionProvider"
        app:showAsAction="always"/>
</menu>

Code

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();
    }
}
1
Sibelius Seraphini