OnCreateOptionsMenu () wird in Fragment nicht aufgerufen


107

Ich habe eine App, die eine Aktivität mit 2 horizontal platzierten Fragmenten hat.

In meiner Aktivität habe ich das Menü aufgeblasen, onCreateOptionsMenu()mit dem ich das Optionsmenü der Aktionsleiste anzeigen kann. Wenn ich jedoch versuche, die Menüelemente der Aktionsleiste von einem meiner Fragmente aus zu aktualisieren, onCreateoptionsmenu()wird das nicht aufgerufen. Daher kann ich das Optionsmenü der Aktionsleiste nicht aktualisieren.

Der Code in meiner Aktivität lautet wie folgt:

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

     }
   }

Antworten:


295

Bei der onCreateView()Methode Ihres Fragments müssen Sie aufrufen setHasOptionsMenu(true), um der Hostaktivität mitzuteilen, dass Ihr Fragment über Menüoptionen verfügt, die hinzugefügt werden sollen.


Ich habe die Änderung vorgenommen, aber die App stürzt ab mit 11-27 01: 55: 34.468: E / AndroidRuntime (12294): Auslöser: java.lang.ClassCastException: com.android.internal.view.menu.MenuItemImpl kann nicht in Android umgewandelt werden .widget.SearchView
Android_programmer_office

Ja, ich habe das Problem gefunden. Ich habe vergessen, getActionView () für searchView hinzuzufügen.
Android_programmer_office

2
Außerdem müssen Sie den void-Typ für onCreateOptionsMenu (Menü menu, MenuInflater inflater) verwenden. Der boolesche Typ funktioniert nicht
Bahaa Hany

15
Wenn Sie Toolbardas Layout Ihrer Aktivität verwenden, stellen Sie sicher, dass Sie setSupportActionBar(your_toolbar)Ihre Aktivität aufrufen . Ansonsten setHasOptionsMenuhat keine Wirkung.
Artkoenig

Du bist mein Liebesbruder :)
Qadir Hussain

30

Wenn Sie ein Thema verwenden , das ActionBar nicht unterstützt, wird OnCreateOptionsMenu () nicht automatisch aufgerufen, selbst wenn Sie alle Java-Codes ordnungsgemäß geschrieben haben.

Sie können AndroidManifest.xml öffnen, den Wert von android: theme in "@android: style / Theme.Holo.Light.DarkActionBar" oder andere Themen ändern, die ActionBar unterstützen.


Ich benutze die Symbolleiste aus der Support-Bibliothek und Theme.AppCompat.Light.NoActionBar als Thema und ich habe das gleiche Problem ... kein Optionsmenü angezeigt..plz Hilfe
Dhruvam Gupta

6
Ich löste es, indem toolbar.inflateMenu(R.menu.menu_custom);
ich

Rufen Sie einfach setSupportActionBar (mToolbar) in Ihrer Aktivität auf und onCreateOptionsMenu in Fragments wird automatisch aufgerufen.
Vít Kapitola

12

das hat bei mir funktioniert

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

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

11

Stellen Sie außerdem sicher, dass die Symbolleisteninstanz, an die Sie übergeben werden

setSupportActionBar(toolbar);

in Ihrer Aktivität ist nicht null, weil Sie keine Ausnahme bekommen, wenn es tatsächlich ist nullund Sie ein paar Stunden verlieren werden, wie ich es getan habe.

Ich habe ButterKnife verwendet , um die Ansichten zu binden, aber versehentlich platziert, setSupportActionBar(toolbar)bevor ich tatsächlich angerufen habeButterKnife.bind()


1
Haris, du bist großartig. Vielen Dank für das Teilen! Ich hatte genau dieses Problem, weil ich Kotlin verwende und Sie oft nicht findViewById usw. ausführen müssen, um die gewünschte Ansicht zu erhalten.
DWndrer

1

Teilen Sie der Hostaktivität einfach mit, dass Ihr Fragment im Konstruktor ein Optionsmenü enthält.

public YourFragment () {setHasOptionsMenu (true);}

Obwohl es bei mir funktioniert hat, wird davon abgeraten, wie im Kommentar von @aldorain angegeben

Anwendungen sollten im Allgemeinen keinen Konstruktor implementieren. Der erste Anwendungscode, der ausgeführt werden kann, wenn das Fragment zur Verwendung bereit ist, befindet sich in onAttach (Aktivität), dem Punkt, an dem das Fragment tatsächlich seiner Aktivität zugeordnet ist.

Fügen Sie stattdessen setHasOptionsMenu (true) in onCreateView () oder onAttach () ein.


Sie sollten keine eigenen Konstruktoren für benutzerdefinierte Fragmente schreiben
Aldorain

1
developer.android.com/reference/android/app/Fragment.html tl; dr 'Anwendungen sollten im Allgemeinen keinen [Fragment] -Konstruktor implementieren.'
Aldorain

0

Wenn Sie ein Thema haben, das Ihnen standardmäßig keine AppBar bietet, und Sie stattdessen eine Symbolleistenansicht verwenden, um diese Funktion bereitzustellen, VERGESSEN SIE NICHT, setSupportActionBar (Symbolleiste) in der onCreate () -Methode der Aktivität aufzurufen, die Ihre hostet Fragmente.

Rufen Sie danach setHasOptionsMenu (true) in Ihrer onCreate () -Fragmentmethode auf.

:) :)


-2

Set setHasOptionsMenu(true)in onCreateView()Verfahren in Fragmente.

@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
Hallo und willkommen bei SO. Bitte posten Sie nicht nur unkommentierte und schlecht formatierte Nur-Code-Antworten, da dies nicht erklärt, was genau das in der Frage beschriebene Problem war. Schauen Sie sich hier für einige allgemeine Tipps, was Antwort eine gute darstellt.
Gero
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.