OnCreateOptionsMenu () nie jest wywoływana we fragmencie

107

Mam aplikację, która ma jedno działanie z 2 fragmentami umieszczonymi poziomo.

W swojej aktywności napompowałem menu za onCreateOptionsMenu()pomocą którego jestem w stanie wyświetlić menu opcji paska akcji. Ale kiedy próbuję zaktualizować elementy menu paska akcji z jednego z moich fragmentów, plik onCreateoptionsmenu()nie jest wywoływany. Dlatego nie mogę zaktualizować menu opcji paska akcji.

Kod w mojej działalności jest następujący:

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

     }
   }
Android_programmer_office
źródło

Odpowiedzi:

296

W onCreateView()metodzie twojego fragmentu musisz zadzwonić, setHasOptionsMenu(true)aby poinformować działanie hosta, że ​​twój fragment ma opcje menu, które chce dodać.

dangVarmit
źródło
Wprowadziłem zmianę, ale aplikacja ulega awarii z 11-27 01: 55: 34.468: E / AndroidRuntime (12294): Spowodowane przez: java.lang.ClassCastException: com.android.internal.view.menu.MenuItemImpl nie można przesłać na Androida .widget.SearchView
Android_programmer_office
tak, znalazłem problem. zapomniałem dodać getActionView () dla searchView.
Android_programmer_office
2
Musisz także użyć typu void dla onCreateOptionsMenu (menu Menu, inflator MenuInflater), typ Boolean nie będzie działać
Bahaa Hany
15
Jeśli używasz Toolbarw układzie swojego działania, upewnij się, że dzwonisz setSupportActionBar(your_toolbar)w swoim działaniu. W przeciwnym razie setHasOptionsMenunie ma żadnego efektu.
artkoenig
Jesteś moją miłością bracie :)
Qadir Hussain
30

Jeśli używasz motywu , który nie obsługuje ActionBar, wtedy OnCreateOptionsMenu () nie zostanie wywołany automatycznie, nawet jeśli poprawnie napisałeś wszystkie kody Java.

Możesz otworzyć AndroidManifest.xml, zmienić wartość android: theme na „@android: style / Theme.Holo.Light.DarkActionBar” lub dowolny inny motyw obsługujący ActionBar.

animalizować
źródło
Używam paska narzędzi z biblioteki wsparcia i Theme.AppCompat.Light.NoActionBar jako motywu i mam ten sam problem ... nie wyświetlono menu
opcji..plz
6
Rozwiązałem to dzwoniąctoolbar.inflateMenu(R.menu.menu_custom);
Dhruvam Gupta
Po prostu wywołaj setSupportActionBar (mToolbar) w swojej aktywności, a onCreateOptionsMenu we fragmentach zostanie wywołane automatycznie.
Vít Kapitola
12

to działało dla mnie

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

    setHasOptionsMenu(true);
    View view = inflater.inflate(R.layout.sample, null);
}
Anisetti Nagendra
źródło
11

Upewnij się również, że przekazujesz instancję paska narzędzi Toolbar

setSupportActionBar(toolbar);

w Twojej Aktywności nie jest null, ponieważ nie dostaniesz wyjątku, jeśli tak jest, nulli stracisz kilka godzin, tak jak ja.

Użyłem ButterKnife do wiązania widoków, ale przypadkowo umieściłem je, setSupportActionBar(toolbar)zanim faktycznie wykonałem połączenieButterKnife.bind()

jack's medulla oblongata
źródło
1
Haris, jesteś niesamowity. Dziękuję za udostępnienie tego! Miałem dokładnie ten problem, ponieważ używam Kotlina i wiele razy nie musisz robić findViewById itp., Aby uzyskać widok, którego potrzebujesz.
DWndrer,
1

Po prostu powiedz działaniu hosta, że ​​twój fragment ma menu opcji w swoim konstruktorze.

public YourFragment () {setHasOptionsMenu (true);}

Chociaż mi się to udało, odradzam, jak napisano w komentarzu @aldorain

Aplikacje generalnie nie powinny implementować konstruktora. Pierwszym miejscem, w którym można uruchomić kod aplikacji, w którym fragment jest gotowy do użycia, jest onAttach (Aktywność), czyli punkt, w którym fragment jest faktycznie powiązany z jego aktywnością.

Więc zamiast tego umieść setHasOptionsMenu (true) w onCreateView () lub onAttach ().

Ken Ratanachai S.
źródło
Nie powinieneś pisać własnych konstruktorów dla niestandardowych fragmentów
aldorain
1
developer.android.com/reference/android/app/Fragment.html tl; dr „Aplikacje zasadniczo nie powinny implementować konstruktora [fragmentu]”.
aldorain
0

Jeśli masz motyw, który domyślnie nie zapewnia paska AppBar i zamiast tego używasz widoku paska narzędzi, aby zapewnić tę funkcję, NIE ZAPOMNIJ wywołać setSupportActionBar (pasek narzędzi) w metodzie onCreate () działania, które obsługuje twoją paprochy.

Następnie wywołaj setHasOptionsMenu (true) w metodzie fragmentu onCreate ().

:)

Moreno
źródło
-2

Ustaw setHasOptionsMenu(true)w onCreateView()metodzie in fragmentu.

@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;
}
Nimisha Patel
źródło
1
Witam i zapraszam do SO. Proszę nie publikować tylko niekomentowanych i źle sformatowanych odpowiedzi zawierających tylko kod, ponieważ nie wyjaśnia to dokładnie, na czym dokładnie polegał problem opisany w pytaniu. Sprawdź tutaj, aby uzyskać ogólne wskazówki dotyczące tego, co stanowi dobrą odpowiedź.
Gero