OnCreateOptionsMenu () не викликається у фрагменті


107

У мене є додаток, який отримав одну активність з 2 фрагментами, розміщеними горизонтально.

У своїй діяльності я завищив меню, використовуючи onCreateOptionsMenu()яке я в змозі відобразити меню параметрів панелі дій. Але коли я намагаюся оновити пункти меню рядка дій з одного з моїх фрагментів, onCreateoptionsmenu()це не викликається. Отже, я не в змозі оновити меню параметрів рядка дій.

Код у моїй діяльності такий:

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

     }
   }

Відповіді:


296

У onCreateView()методі фрагмента вам потрібно зателефонувати, setHasOptionsMenu(true)щоб повідомити активності хоста, що ваш фрагмент має параметри меню, які він хоче додати.


Я вніс зміни, але програма виходить з ладу з 11-27 01: 55: 34.468: E / AndroidRuntime (12294): Викликано: java.lang.ClassCastException: com.android.internal.view.menu.MenuItemImpl не можна передавати на android .widget.SearchView
Android_programmer_office

так, я знайшов проблему. забув додати getActionView () для searchView.
Android_programmer_office

2
Крім того, ви повинні використовувати тип пустоти для onCreateOptionsMenu (меню меню, надувальник MenuInflater) булевий тип не працюватиме
Bahaa Hany

15
Якщо ви використовуєте Toolbarв макеті своєї активності, переконайтеся, що ви телефонуєте setSupportActionBar(your_toolbar)у своїй активності. В іншому випадку setHasOptionsMenuне має ефекту.
artkoenig

Ти мій любов брато :)
Кадір Хусейн

30

Якщо ви використовуєте тему , яка не підтримує ActionBar, OnCreateOptionsMenu () не буде викликатися автоматично, навіть якщо ви правильно написали всі коди Java.

Ви можете відкрити AndroidManifest.xml, змінити значення android: теми на "@android: style / Theme.Holo.Light.DarkActionBar" або будь-які інші теми, що підтримують ActionBar.


Я використовую панель інструментів з бібліотеки підтримки та Theme.AppCompat.Light.NoActionBar як тема, і я зіткнувся з тією ж проблемою ... меню не відображається без опцій.
Довідка. plz

6
Я вирішив це, зателефонувавшиtoolbar.inflateMenu(R.menu.menu_custom);
Dhruvam Gupta

Просто зателефонуйте setSupportActionBar (mToolbar) у своїй діяльності та onCreateOptionsMenu у фрагментах буде викликано автоматично.
Vít Kapitola

12

це працювало для мене

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

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

11

Також переконайтеся, що екземпляр Панелі інструментів ви переходите

setSupportActionBar(toolbar);

у вашій діяльності немає null, тому що ви не отримаєте винятку, якщо це дійсно, nullі ви втратите пару годин, як я.

Я використовував ButterKnife, щоб прив’язати погляди, але випадково розмістив його, setSupportActionBar(toolbar)перш ніж насправді зателефонувавButterKnife.bind()


1
Харісе, ти приголомшливий. Дякуємо, що поділилися цим! У мене була така точна проблема, тому що я використовую Kotlin і багато разів вам не потрібно робити FindViewById тощо, щоб отримати потрібний погляд.
DWndrer

1

Просто скажіть активності хоста, що ваш фрагмент має меню параметрів у своєму конструкторі.

public YourFragment () {setHasOptionsMenu (true);}

Хоча це працювало і для мене, але це відлякує, як зазначається в коментарі від @aldorain

Зазвичай програми не повинні реалізувати конструктор. Код програми на першому місці може працювати там, де фрагмент готовий до використання, знаходиться в OnAttach (Діяльність), точка, де фрагмент насправді пов'язаний з його активністю.

Тож поставте замість setHasOptionsMenu (true) в onCreateView () або onAttach ().


Не варто писати власні конструктори для користувацьких фрагментів
aldorain

1
developer.android.com/reference/android/app/Fragment.html tl; dr "Програми, як правило, не повинні реалізувати конструктор [Фрагмент]."
aldorain

0

У вас є тема, яка не надає вам AppBar за замовчуванням, і ви використовуєте подання на панелі інструментів, щоб надати цю функцію замість цього, НЕ ЗАБУДУЙТЕ ЗАБЕЗПЕЧИТИ викликати setSupportActionBar (панель інструментів) у методі onCreate () діяльності, яка розміщує ваш фрагменти.

Після цього виклику setHasOptionsMenu (true) у вашому методі фрагмента onCreate ().

:)


-2

Набір setHasOptionsMenu(true)в onCreateView()способі в фрагменті.

@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
Привіт і ласкаво просимо до SO. Будь ласка, не публікуйте коментовані та неправильно відформатовані відповіді лише для коду, оскільки це не пояснює, у чому саме була проблема, описана у питанні. Перевірте тут деякі загальні поради про те, що являє собою хороший відповідь.
Геро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.