OnCreateOptionsMenu () non chiamato in Fragment


107

Ho un'app che ha un'attività con 2 frammenti posizionati orizzontalmente.

Nella mia attività ho gonfiato il menu utilizzando il onCreateOptionsMenu()quale sono in grado di visualizzare il menu delle opzioni della barra delle azioni. Ma quando provo ad aggiornare le voci di menu della barra delle azioni da uno dei miei frammenti, il file onCreateoptionsmenu()non viene chiamato. Quindi, non sono in grado di aggiornare il menu delle opzioni della barra delle azioni.

Il codice nella mia attività è il seguente:

myActivity.java

package com.andr.androidtablelist;

import java.io.IOException;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.andr.fragments.ListLeftFragment;
import com.andr.utils.DBHelper;

      public class TabletActivity extends Activity {
    ActionBar actionBar = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DBHelper dbhelper;
        dbhelper = new DBHelper(this);
        try {
            dbhelper.createDatabase();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        setContentView(R.layout.activity_tablet);
        actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(false);
        getFragmentManager().beginTransaction()
                .replace(R.id.master, ListLeftFragment.newInstance()).commit();
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            Toast.makeText(
                    getApplicationContext(),
                    "Back Stack Count::"
                            + getFragmentManager().getBackStackEntryCount(),
                    Toast.LENGTH_LONG).show();
            if (getFragmentManager().getBackStackEntryCount() == 1) {
                actionBar.setDisplayHomeAsUpEnabled(false);
            }
            if (getFragmentManager().getBackStackEntryCount() > 1) {
                getFragmentManager().popBackStack();

            }
            return true;

        }
        return super.onOptionsItemSelected(item);
    }

}
      // http://www.vogella.com/articles/AndroidListView/article.html

myFragment.java

      package com.andr.fragments;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;

import com.andr.androidtablelist.R;
import com.andr.helper.LazyHelper;

   public class ListLeftFragment extends Fragment{
    private static ListLeftFragment listFragment = null;

    public static ListLeftFragment newInstance(){
        listFragment = new ListLeftFragment();      
        return listFragment;
    }

     @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);


    }

     @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
         View v =  inflater.inflate(R.layout.fragment_listlayout, container,false);
         getActivity().invalidateOptionsMenu();
         ListView lv = (ListView)v.findViewById(R.id.lview);
         String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
                    "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
                    "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux",
                    "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",
                    "Android", "iPhone", "WindowsMobile" };
         getActivity().getActionBar().setTitle("LeftList");

          ArrayList<String> list = new ArrayList<String>();
         LazyHelper lHelper = new LazyHelper(getActivity());
         list = lHelper.getLazyDetials();

           /* for (int i = 0; i < values.length; ++i) {
              list.add(values[i]);
            }
            final StableArrayAdapter adapter = new StableArrayAdapter(getActivity(),
                android.R.layout.simple_list_item_1, list);*/
            LeftListAdapter lAdapter = new LeftListAdapter(getActivity(),list);
            lv.setAdapter(lAdapter);
            lv.setOnItemClickListener(new OnItemClickListener()
            {

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1,
                        int pos, long arg3) {
                    final String clickedData = (String)arg0.getItemAtPosition(pos);
                    Bundle bundle = new Bundle();
                    bundle.putString("clickedItemName", clickedData);
                    Fragment detailFragment = DetailFormRightFragment.newInstance();
                    detailFragment.setArguments(bundle);
                    getActivity().getFragmentManager().beginTransaction().replace(R.id.details, detailFragment).addToBackStack(null).commit();
                }

            }
                    );
         return v;
    }


     @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        getActivity().getMenuInflater().inflate(R.menu.search, menu);
        SearchView searchView=(SearchView)menu.findItem(R.id.search);
        searchView.setIconifiedByDefault(true);
    } 

     @Override
    public boolean onOptionsItemSelected(MenuItem item) {

         super.onOptionsItemSelected(item);
         return false;
    }


     @Override
    public void onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
        /*MenuItem item;
        menu.clear();
        getActivity().getMenuInflater().inflate(R.menu.search, menu);
        SearchView searchView=(SearchView)menu.findItem(R.id.search);
        searchView.setIconifiedByDefault(true);*/
    }

     private class StableArrayAdapter extends ArrayAdapter<String> {

            HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

            public StableArrayAdapter(Context context, int textViewResourceId,
                List<String> objects) {
              super(context, textViewResourceId, objects);
              for (int i = 0; i < objects.size(); ++i) {
                mIdMap.put(objects.get(i), i);
              }
            }

            @Override
            public long getItemId(int position) {
              String item = getItem(position);
              return mIdMap.get(item);
            }

            @Override
            public boolean hasStableIds() {
              return true;
            }

          }

     private class LeftListAdapter extends BaseAdapter implements OnClickListener {
         private Context mcontext;
         ArrayList<String> listData;
         private  LayoutInflater inflater=null;
         public LeftListAdapter(Context context, ArrayList<String> listItems) {
              mcontext=context;
              listData=listItems;
              inflater = (LayoutInflater)mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         }

        @Override
        public int getCount() {
            return listData.size();
        }

        @Override
        public Object getItem(int arg0) {
            return null;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View view, ViewGroup arg2) {
            // create a ViewHolder reference
            View vi=view;
            if(vi==null){
                vi = inflater.inflate(R.layout.item, null);
            }
            TextView text=(TextView)vi.findViewById(R.id.text);
            text.setText(listData.get(position));
            vi.setOnClickListener(this);
            return vi;
        }

        @Override
        public void onClick(View vi) {
            TextView text=(TextView)vi.findViewById(R.id.text);
            Bundle bundle = new Bundle();
            bundle.putString("clickedItemName", text.getText().toString());
            Fragment detailFragment = DetailFormRightFragment.newInstance();
            detailFragment.setArguments(bundle);
            getActivity().getFragmentManager().beginTransaction().replace(R.id.details, detailFragment).addToBackStack(null).commit();          
        }

     }
   }

Risposte:


296

Nel onCreateView()metodo del tuo frammento , devi chiamare setHasOptionsMenu(true)per dire all'attività dell'host che il tuo frammento ha opzioni di menu che vuole aggiungere.


Ho apportato la modifica, ma l'app si arresta in modo anomalo con 11-27 01: 55: 34.468: E / AndroidRuntime (12294): causato da: java.lang.ClassCastException: com.android.internal.view.menu.MenuItemImpl non può essere trasmesso ad Android .widget.SearchView
Android_programmer_office

sì, ho trovato il problema. ho dimenticato di aggiungere getActionView () per searchView.
Android_programmer_office

2
Inoltre devi usare il tipo void per onCreateOptionsMenu (Menu menu, MenuInflater inflater) il tipo booleano non funzionerà
Bahaa Hany

15
Se stai utilizzando Toolbarnel layout della tua attività, assicurati di chiamare la setSupportActionBar(your_toolbar)tua attività. Altrimenti setHasOptionsMenunon ha effetto.
artkoenig

Sei il mio amore fratello :)
Qadir Hussain

30

Se stai utilizzando un tema che non supporta ActionBar, OnCreateOptionsMenu () non verrà chiamato automaticamente, anche se hai scritto correttamente tutti i codici Java.

Puoi aprire AndroidManifest.xml, modificare il valore di android: theme in "@android: style / Theme.Holo.Light.DarkActionBar" o qualsiasi altro tema che supporta ActionBar.


Sto usando la barra degli strumenti dalla libreria di supporto e Theme.AppCompat.Light.NoActionBar come tema e sto affrontando lo stesso problema ... nessun menu di opzioni visualizzato..plz help
Dhruvam Gupta

6
L'ho risolto chiamandotoolbar.inflateMenu(R.menu.menu_custom);
Dhruvam Gupta

Basta chiamare setSupportActionBar (mToolbar) nella tua attività e onCreateOptionsMenu in Fragments verrà chiamato automaticamente.
Vít Kapitola

12

questo ha funzionato per me

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    setHasOptionsMenu(true);
    View view = inflater.inflate(R.layout.sample, null);
}

11

Inoltre, assicurati che l'istanza di Google Toolbar a cui stai passando

setSupportActionBar(toolbar);

nella tua Attività no null, perché non otterrai un'eccezione se lo è davvero nulle perderai un paio d'ore come ho fatto io.

Ho usato ButterKnife per legare le viste, ma l' setSupportActionBar(toolbar)ho inserito accidentalmente prima di aver effettivamente chiamatoButterKnife.bind()


1
Haris, sei fantastica. Grazie per aver condiviso questo! Ho avuto questo problema esatto perché sto usando Kotlin e molte volte non devi fare findViewById, ecc ... per ottenere la vista di cui hai bisogno.
DWndrer

1

Dì semplicemente all'attività host che il tuo frammento ha il menu delle opzioni nel suo costruttore.

public YourFragment () {setHasOptionsMenu (true);}

Sebbene abbia funzionato per me, è sconsigliato come indicato nel commento di @aldorain

Le applicazioni generalmente non dovrebbero implementare un costruttore. Il primo posto in cui il codice dell'applicazione può essere eseguito dove il frammento è pronto per essere utilizzato è in onAttach (Activity), il punto in cui il frammento è effettivamente associato alla sua attività.

Quindi metti setHasOptionsMenu (true) in onCreateView () o onAttach () invece.


Non dovresti scrivere i tuoi costruttori per i frammenti personalizzati
aldorain

1
developer.android.com/reference/android/app/Fragment.html tl; dr "Le applicazioni generalmente non dovrebbero implementare un costruttore [Fragment]."
aldorain

0

Se hai un tema che non ti fornisce una AppBar per impostazione predefinita e stai utilizzando una visualizzazione della barra degli strumenti per fornire questa funzionalità, NON DIMENTICARE DI chiamare setSupportActionBar (barra degli strumenti) nel metodo onCreate () dell'attività che ospita il tuo frammenti.

Dopo quella chiamata setHasOptionsMenu (true) nel tuo metodo di frammentazione onCreate ().

:)


-2

Situato setHasOptionsMenu(true)nel onCreateView()metodo frammento.

@Override

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
 {
    Viewroot=inflater.inflate(R.layout.fragment_client_requestfragment,container,false);
  hideKeyboard();
    getemail = getArguments().getString("email_id");
    Log.e("email_id from activity",getemail);
    setHasOptionsMenu(true);
    return root;
}

1
Ciao e benvenuto in SO. Si prega di non pubblicare solo risposte di codice non commentate e formattate in modo errato in quanto ciò non spiega quale fosse esattamente il problema descritto nella domanda. Controlla qui per alcuni suggerimenti generali su ciò che costituisce una buona risposta.
Gero
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.