web-dev-qa-db-fra.com

Comment mettre à jour un élément de menu affiché dans la barre d'actions?

J'ai une activité qui a 2 fragments. Les deux sont ListFragments et les deux contribuent MenuItems au menu. J'ai un MenuItem que j'ai défini l'attribut Android: showAsAction pour l'afficher comme un bouton sur la barre de contrôle. Ce qui fonctionne bien.

Maintenant, le MenuItem dépend de l'état. C'est une option du menu Pause/Reprendre pour suspendre et reprendre une file d'attente. Mon problème est que je n'arrive pas à comprendre comment définir sa statue initiale lorsque le fragment est créé.

Son état dépend du fait que la file d'attente est en pause ou non. J'ai donc une AsyncTask qui obtient la file d'attente et définit un booléen (en pause) en fonction de l'état de la file d'attente. J'appelle onPrepareOptionsMenu pour définir le texte de l'élément de menu Pause en fonction du dernier état connu de la file d'attente, ce qui fonctionne parfaitement si je laisse le MenuItem dans le menu actuel. Vous appuyez sur l'icône de menu et onPrepareOptionsMenu est déclenché et le menu est mis à jour avant qu'il ne soit affiché.

Le problème est que, si je mets le même MenuItem sur la barre d’action (showAsAction), comment puis-je le forcer à se mettre à jour sans avoir à appeler onPrepareOptionsMenu? Je dois être capable de le faire car au premier lancement de l'application, j'envoie une demande pour obtenir la file d'attente, mais la tâche revient après la configuration et l'affichage du ActionBar. J'ai créé un gestionnaire dans mon fragment qui est appelé à chaque fois que je reçois une mise à jour de la file d'attente, mais à partir de là, comment puis-je mettre à jour le texte de mon MenuItem sur la barre de contrôle? Je n'arrive pas à trouver le moyen de le manipuler avec le menu actuellement défini, sauf dans onPrepareOptionMenu.

Rob W.

91
brockoli

Option n ° 1: Essayez invalidateOptionsMenu() . Je ne sais pas si cela forcera un redessin immédiat de la barre d'action ou non.

Option n ° 2: Voir si getActionView() renvoie quoi que ce soit pour le MenuItem affecté. Il est possible que showAsAction crée automatiquement des vues d'action pour vous. Si c'est le cas, vous pouvez probablement activer/désactiver ce View.

Je n'arrive pas à trouver le moyen de le manipuler avec le menu actuellement défini, sauf dans onPrepareOptionMenu.

Vous pouvez accrocher à l'objet Menu qui vous a été remis onCreateOptionsMenu(). Citant le docs :

Vous pouvez conserver en toute sécurité le menu (et tous les éléments créés à partir de celui-ci), en le modifiant comme vous le souhaitez, jusqu'à la prochaine fois que onCreateOptionsMenu () sera appelé.

170
CommonsWare

dans mon cas: invalidateOptionsMenu vient de ré-ajuster le texte à l'original, mais l'accès direct à l'élément de menu et la réécriture du texte souhaité ont fonctionné sans problème:

if (mnuTopMenuActionBar_ != null) {
    MenuItem mnuPageIndex = mnuTopMenuActionBar_
        .findItem(R.id.menu_magazin_pageOfPage_text);

    if (mnuPageIndex != null) {
        if (getScreenOrientation() == 1) {
            mnuPageIndex.setTitle((i + 1) + " von " + pages);
        }
        else {
            mnuPageIndex.setTitle(
                (i + 1) + " + " + (i + 2) + " " + " von " + pages);
        }
        // invalidateOptionsMenu();
    }
}

en raison du commentaire ci-dessous, j'ai pu accéder à l'élément de menu via le code suivant:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.magazine_swipe_activity, menu);
    mnuTopMenuActionBar_ = menu;
    return true;
}
12
cV2

Pour actualiser le menu de Fragment, appelez simplement:

getActivity().invalidateOptionsMenu();
8
CoolMind

J'ai utilisé ce code:

public boolean onPrepareOptionsMenu (Menu menu) {       
    MenuInflater inflater = getMenuInflater();
    TextView title  = (TextView) findViewById(R.id.title);
    menu.getItem(0).setTitle(
        getString(R.string.payFor) + " " + title.getText().toString());
    menu.getItem(1).setTitle(getString(R.string.payFor) + "...");
    return true;        
}

Et a travaillé comme un charme pour moi, vous pouvez trouver OnPrepareOptionsMenu ici

4
ASK

Suivez d'abord les deux lignes de codes pour mettre à jour les éléments de la barre d'action avant de définir une condition dans oncreateOptionMenu (). Par exemple:

Boolean mISQuizItemSelected = false;

/**
 * Called to inflate the action bar menus
 *
 * @param menu
 *      the menu
 *
 * @return true, if successful
 */

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu items for use in the action bar

    inflater.inflate(R.menu.menu_demo, menu);

    //condition to hide the menus
    if (mISQuizItemSelected) {
        for (int i = 0; i < menu.size(); i++) {
            menu.getItem(i).setVisible(false);
        }
    }

    return super.onCreateOptionsMenu(menu);
}

/**
 * Called when the item on the action bar being selected.
 *
 * @param item
 *      menuitem being selected
 *
 * @return true if the menuitem id being selected is matched
 * false if none of the menuitems id are matched
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getId() == R.id.action_quiz) {
        //to navigate based on the usertype either learner or leo
        mISQuizItemSelected = true;

        ActionBar actionBar = getActionBar();
        invalidateOptionMenu();
    }
}
2
saranya

Par souci de clarté, j’ai pensé qu’un exemple direct de saisie sur une ressource pouvait être illustré à partir des éléments suivants qui, à mon avis, contribuaient à la réponse à cette question par un exemple direct rapide.

private MenuItem menuItem_;

@Override
public boolean onCreateOptionsMenu(Menu menuF) 
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_layout, menuF);
    menuItem_ = menuF.findItem(R.id.menu_item_identifier);
    return true;
}

Dans ce cas, vous conservez une référence MenuItem au début, puis vous en changez l'état (pour les changements d'état des icônes, par exemple) ultérieurement.

1
Jay Snayder