web-dev-qa-db-fra.com

(Obsolète) Fragment onOptionsItemSelected n'étant pas appelé

EDIT: Cette question était pour la barre d'action obsolète sherlock. La bibliothèque de support Android devrait être utilisée à la place maintenant

J'ai ajouté une option de menu de la barre d'actions appelée partage pour ma fragment qui apparaît mais l'événement de sélection n'est pas intercepté. 

Je l'ajoute comme ça

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    MenuItem item = menu.add(0, 7,0, R.string.share);
    item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

Essayer de le capturer à la fois dans la fragment et le fragment activity comme

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case 7:
            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("text/plain");
            share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!");
            startActivity(Intent.createChooser(share, "Share Text"));
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

et j'ai setHasOptionsMenu(true); dans onCreate().

80
user1634451

Editer pour utiliser la barre d’action sherlock

Je devais utiliser 

public boolean onMenuItemSelected(int featureId, MenuItem item) {

dans l'activité principale pour capturer l'élément de menu 

2
user1634451

Les mêmes problèmes m'est arrivé: 

onMenuItemSelected n'a pas été appelé dans Fragment

La recherche Google ne peut pas trouver de solution, et ajouter la méthode MenuItemSelected dans FragmentActivity ne le résout pas.

Enfin, résolvez-le en suivant la référence à http://developer.Android.com/guide/topics/ui/actionbar.html

Remarque: Si vous avez ajouté l'élément de menu d'un fragment, via le rappel onCreateOptionsMenu de la classe Fragment, le système appelle la méthode onOptionsItemSelected () respective pour ce fragment lorsque l'utilisateur sélectionne l'un des éléments du fragment. Cependant, l'activité a d'abord l'occasion de gérer l'événement. Le système appelle donc onOptionsItemSelected () avant de rappeler le même rappel pour le fragment.

Ce qui signifie que si vous n'avez pas ce gestionnaire d'élément de menu dans onOptionsItemSelected () sur l'activité, onOptionsItemSelected () sur le fragment sera appelé.

Code comme suit ----- Supprimez le gestionnaire pour R.action.add sur FragmentActivity):

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case Android.R.id.home:
            popBackStack();             
            return true;        
        case R.id.action_search:
            searchAction();
            return true;
        case R.id.action_logout:
            userLogout();
            return true;
        //case R.id.action_add:
            //return true;    
        default:
            return super.onOptionsItemSelected(item);
    }   
}

Et le gestionnaire de R.action.add sur Fragment ressemble à ceci:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("onOptionsItemSelected","yes");
    switch (item.getItemId()) {
        case R.id.action_add:
            add();
            return true;    
        default:
            return super.onOptionsItemSelected(item);
    }
}

Enfin, n'oubliez pas d'ajouter 

    setHasOptionsMenu(true);

dans votre méthode onCreate dans Fragment

145
Felixqk

J'ai eu le même problème, mais je pense qu'il est préférable de résumer et d'introduire la dernière étape pour le faire fonctionner:

  1. Ajoutez la méthode setHasOptionsMenu(true) dans la méthode onCreate(Bundle savedInstanceState) de votre fragment.

  2. Remplacez onCreateOptionsMenu(Menu menu, MenuInflater inflater) (si vous voulez faire quelque chose de différent dans le menu de votre fragment) et les méthodes onOptionsItemSelected(MenuItem item) dans votre fragment.

  3. Dans la méthode onOptionsItemSelected(MenuItem item) de votre activité, veillez à renvoyer false lorsque l'action de l'élément de menu serait implémentée dans la méthode onOptionsItemSelected(MenuItem item) de Fragment.

Un exemple:

Activité

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Do Activity menu item stuff here
        return true;
    case R.id.fragment_menu_item:
        // Not implemented here
        return false;
    default:
        break;
    }

    return false;
}

Fragment

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    ....
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Not implemented here
        return false;
    case R.id.fragment_menu_item:
        // Do Fragment menu item stuff here
        return true;
    default:
        break;
    }

    return false;
}
125
Marco HC

J'ai remarqué que la solution que les gens vous proposaient était d'implémenter le code de votre élément de menu dans l'activité plutôt que dans le fragment ..__ Je pense que cela aurait l'air beaucoup plus génial si vous aviez implémenté le code dans le fragment plutôt que dans l'activité 'cos à mon avis, il a l'air mieux . Pour ce faire, procédez comme suit:

Activité

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu, menu);      
        return true;
    }

 @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {            
        switch (item.getItemId())
        {
            case R.id.SomeIDInTheMenueOfTheActivity:
            {
               //something();
                break;
            }
            default:
             //do something default and add the code under : 
             return super.onOptionsItemSelected(item);
        }
        return true;
    }

Fragment

 @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);  
            setHasOptionsMenu(true);      
        }

  @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {           
        super.onCreateOptionsMenu(menu, inflater);
    }

     @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            switch (item.getItemId())
            {           
                case R.id.SomeIDInFragmentMenue:
                {             
                    break;
                }

                default:
                    return super.onOptionsItemSelected(item);
            }

            return true;
        }

Maintenant les lignes (et les goûts): "return super.onOptionsItemSelected (item);" dans l'activité et le fragment sont très importants, car comme si vous suiviez le code dans le débogage, vous verrez que les fonctions d'événements du menu seront appelées en premier sur l'activité, et si l'élément ne correspond pas à l'identifiant dans le commutateur de l'activité. cas, la ligne degault: "super.onOptionsItemSelected (item);" appellera la fonction onOptionsItemSelected sur le fragment, comme nous le souhaitions ..__ (si vous avez plusieurs fragments, assurez-vous d’avoir cette ligne également, car la hiérarchie des appels peut être quelque peu compliquée).

5
Malfonde

c'est si simple que vous pouvez le faire dans votre fragment pour vous assurer que votre action écoutera correctement:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}
2
Mohamed Hussien

J'utilise actionbarsherlock. Cela a fonctionné pour moi:

1) Créer le menu dummy_menu.xml

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_height="match_parent" Android:layout_width="fill_parent" >
<item
      Android:title=""
      Android:showAsAction="never"
      Android:id="@+id/dummyMenu"
        />

2) En activité, gonflez le menu comme ceci:

@Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
    com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
   inflater.inflate(R.menu.dummy_menu,menu);
   return super.onCreateOptionsMenu(menu);
}

3) Dans les fragments onCreateView, appelez setHasOptionsMenu (true) et substituez onCreateOptionsMenu et onOptionsItemSelected masquent également le menu factice comme ceci (dans le fragment)

    @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_actions, menu);
    MenuItem item = menu.findItem(R.id.dummyMenu);
    item.setVisible(false);
    super.onCreateOptionsMenu(menu, inflater);
}

J'espère que ça aide quelqu'un.

2
okkko

J'ai eu ce problème. C’est parce que j’ignorais la mauvaise méthode

onOptionsItemSelected (élément com.actionbarsherlock.view.MenuItem) est ce que j'ai utilisé.

Assurez-vous que vous utilisez le bon!

0
Barrie Galitzky

vous devez ajouter ce code toolbar.bringToFront(); la prochaine barre d'outils Set dans votre activité

 public class MainActivity extends AppCompatActivity {
     protected void onCreate(Bundle savedInstanceState) {
        ...

        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("Yazd");
        setSupportActionBar(toolbar);
        toolbar.bringToFront(); // <<= add here
         ...
0
Mahdi Afkhami

Vous ne vous enchaînez pas à la super-classe dans les méthodes d'activité. Merci de faire en sorte que onCreateOptionsMenu () renvoie super.onCreateOptionsMenu (menu) et que onOptionsItemSelected () renvoie super.onOptionsItemSelected (item) (sauf pour l'élément que vous manipulez, qui doit être true pour indiquer que vous avez géré l'événement)

0
Divyesh Murani