ti-enxame.com

(Deprecado) Fragmento onOptionsItemSelecionado não sendo chamado

EDIT: Esta pergunta foi para a barra de ação sherlock obsoleta. A biblioteca de suporte do Android deve ser usada agora

Eu adicionei uma opção de menu de barra de ação chamada share para minha fragment que aparece, mas o evento de seleção não está sendo capturado 

Estou adicionando assim

@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);
}

Tentando capturá-lo tanto no fragment quanto no fragment activity como

@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);
    }
}

e tenho setHasOptionsMenu(true); na onCreate().

80
user1634451

Editar para uso de sherlock actionbar

Eu tive que usar 

public boolean onMenuItemSelected(int featureId, MenuItem item) {

na atividade principal para capturar o item de menu 

2
user1634451

Mesmos problemas me aconteceram: 

eventos onMenuItemSelected não foram chamados no Fragment

O google pesquisado não consegue encontrar uma solução e o método onMenuItemSelected no FragmentActivity não resolve o problema.

Por fim, resolva-o seguindo a referência a http://developer.Android.com/guide/topics/ui/actionbar.html

Nota: Se você incluiu o item de menu de um fragmento, por meio do retorno de chamada onCreateOptionsMenu da classe Fragment, o sistema chamará o respectivo método onOptionsItemSelected () para esse fragmento quando o usuário selecionar um dos itens do fragmento. No entanto, a atividade tem a chance de manipular o evento primeiro, portanto, o sistema chama onOptionsItemSelected () na atividade antes de chamar o mesmo retorno de chamada para o fragmento.

O que significa somente se você não tiver esse manipulador de item de menu em onOptionsItemSelected () na atividade, o onOptionsItemSelected () no fragmento será chamado.

Codifique como segue ----- Remova o manipulador para R.action.add em 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);
    }   
}

E o manipulador de R.action.add no Fragment se parece com isto:

@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);
    }
}

Finalmente, lembre-se de adicionar 

    setHasOptionsMenu(true);

no seu método onCreate no Fragment

145
Felixqk

Eu tive o mesmo problema, mas acho melhor resumir e apresentar o último passo para fazê-lo funcionar:

  1. Adicione o método setHasOptionsMenu(true) no método onCreate(Bundle savedInstanceState) do seu Fragment.

  2. Substitua onCreateOptionsMenu(Menu menu, MenuInflater inflater) (se você quiser fazer algo diferente no menu do seu Fragment) e onOptionsItemSelected(MenuItem item) métodos no seu Fragment.

  3. Dentro do método onOptionsItemSelected(MenuItem item) da sua Activity, certifique-se de retornar false quando a ação do item de menu for implementada no método onOptionsItemSelected(MenuItem item) do Fragment.

Um exemplo:

Atividade

@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;
}

Fragmento

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

Tenho notado que a solução que as pessoas lhe deram foi implementar o código para o seu item de menue na atividade, em vez do fragmento. Eu acho que parecerá muito mais orgenizado se você tivesse implementado o código no fragmento a atividade porque na minha opinião parece melhor. Para fazer isso, faça o seguinte:

Atividade

@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;
    }

Fragmento

 @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;
        }

Agora as linhas (e os gostos): "return super.onOptionsItemSelected (item);" na atividade e no fragmento são super importantes, pois como se você seguisse o código em debug, você veria que as funções de eventos menue serão chamadas primeiro na Activity, e se o item não coincidir com as id's no switch da atividade caso, a linha de demarcação: "super.onOptionsItemSelected (item);" chamará a função onOptionsItemSelected no fragmento, como desejamos. (se você tiver muitos fragmentos, certifique-se de ter essa linha neles também, pois a hierarquia de chamadas pode ser um pouco complicada).

5
Malfonde

é tão simples que você pode fazer isso em seu fragmento para garantir que sua ação seja ouvida corretamente:

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

Estou usando actionbarsherlock. Isso funcionou para mim:

1) Crie o 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) Na atividade inflar o menu como este:

@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) Em fragmentos onCreateView call setHasOptionsMenu (true) e sobrescrever onCreateOptionsMenu e onOptionsItemSelected também escondem o dummyMenu como este (em fragmento)

    @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);
}

Espero que ajude alguém.

2
okkko

Eu tive esse problema. Foi porque eu estava substituindo o método errado

onOptionsItemSelected (com.actionbarsherlock.view.MenuItem item) é o que eu usei.

Verifique se você está usando o caminho certo!

0
Barrie Galitzky

Você não está encadeando a superclasse nos métodos de atividade. Por favor, tenha onCreateOptionsMenu () retornando super.onCreateOptionsMenu (menu), e tenha onOptionsItemSelected () return super.onOptionsItemSelected (item) (exceto pelo item que você está manipulando, que deve retornar true para indicar que você tratou o evento)

0
Divyesh Murani