Android: изменение видимости элементов меню с изменением фрагмента

Я хочу изменить видимость элементов меню активности фрагмента (абс), когда когда-либо меняю фрагмент в активности. Фрагменты являются объектами SherlockListFragments.

Элементы меню, которые я хочу показать / скрыть, являются прядильщиками, которые я создаю при создании меню:

public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. MenuInflater inflater = getSupportMenuInflater(); IcsSpinner herbSortSpinner = new IcsSpinner(this, null, R.attr.actionDropDownStyle); SpinnerAdapter herbSortSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.herb_sort_elements, android.R.layout.simple_spinner_dropdown_item); herbSortSpinner.setAdapter(herbSortSpinnerAdapter); herbSortSpinner.setOnItemSelectedListener(this); herbSortSpinner.setId(HERB_SPINNER_ID); menu.add(R.string.menu_sort).setActionView(herbSortSpinner).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); IcsSpinner noteSortSpinner = new IcsSpinner(this, null, R.attr.actionDropDownStyle); SpinnerAdapter noteSortSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.note_sort_elements, android.R.layout.simple_spinner_dropdown_item); noteSortSpinner.setAdapter(noteSortSpinnerAdapter); noteSortSpinner.setOnItemSelectedListener(this); noteSortSpinner.setId(NOTE_SPINNER_ID); menu.add(R.string.menu_sort).setActionView(noteSortSpinner).setVisible(false).setEnabled(false).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); inflater.inflate(R.menu.activity_lexicon, menu); menuHolder.setMenu(menu); return true; } 

Моя логика для переключения фрагментов:

 public boolean onNavigationItemSelected(int position, long itemId) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); switch(position) { case 0: List<Herb> herbList = findHerbsByIntent(getHerbLocale()); HerbListFragment herbListFragment = new HerbListFragment(); herbListFragment.setListAdapter(new HerbListAdapter(this, getHerbLocale(), herbList)); fragmentTransaction.replace(R.id.fragment_container, herbListFragment, HERB_LIST_FRAGMENT_TAG); //menuHolder.showHerbsSpinner(); break; case 1: SymptomListFragment symptomListFragment = new SymptomListFragment(); symptomListFragment.setListAdapter(new SymptomListAdapter(this, getDefaultSymptomLocale())); fragmentTransaction.replace(R.id.fragment_container, symptomListFragment, SYMPTOM_LIST_FRAGMENT_TAG); //menuHolder.showHerbsSpinner(); break; case 2: NoteRepository noteRepository = new NoteRepository(this); List<Note> notes = noteRepository.getNoticables(ReferedType.HERB); NoteListFragment noteListFragment = new NoteListFragment(); noteListFragment.setListAdapter(new NoteListAdapter(this, getHerbLocale(), notes)); fragmentTransaction.replace(R.id.fragment_container, noteListFragment, NOTE_LIST_FRAGMENT_TAG); //menuHolder.showNotesSpinner(); break; case 3: FavoriteRepository favoriteRepository = new FavoriteRepository(this); Set<Integer> favoriteHerbs = favoriteRepository.getFavorables(ReferedType.HERB); List<Herb> favoriteHerbList = herbRepository.getHerbsByIds(favoriteHerbs, getHerbLocale()); FavoriteHerbListFragment favoriteHerbListFragment = new FavoriteHerbListFragment(); favoriteHerbListFragment.setListAdapter(new HerbListAdapter(this, getHerbLocale(), favoriteHerbList)); fragmentTransaction.replace(R.id.fragment_container, favoriteHerbListFragment, HERB_LIST_FRAGMENT_TAG); //menuHolder.showHerbsSpinner(); break; } fragmentTransaction.commit(); return true; } 

Моя первая идея состояла в том, чтобы удерживать объект меню в классе держателя и манипулировать им там всякий раз, когда я переключаю фрагмент (в каждом случае выше).

 static class MenuHolder { private Menu mMenu; void setMenu(Menu menu) { mMenu = menu; } void showNotesSpinner() { if (mMenu != null) { mMenu.findItem(HERB_SPINNER_ID).setVisible(false).setEnabled(false); mMenu.findItem(NOTE_SPINNER_ID).setVisible(true).setEnabled(true); } } void showHerbsSpinner() { if (mMenu != null) { mMenu.findItem(NOTE_SPINNER_ID).setVisible(false).setEnabled(false); mMenu.findItem(HERB_SPINNER_ID).setVisible(true).setEnabled(true); } } } 

Моя проблема заключается в том, что нет элемента меню с данным идентификатором, которые являются локальными константами активности. Я получаю NPE здесь. У кого-нибудь есть идея, как я могу это исправить? Есть ли лучший способ изменить меню при переключении фрагментов?

С уважением Карстен

Solutions Collecting From Web of "Android: изменение видимости элементов меню с изменением фрагмента"

Есть ли лучший способ изменить меню при переключении фрагментов?

Возможно :).

  • В своем фрагменте onCreate добавьте следующее:

    SetHasOptionsMenu (true);

Документ:

Сообщайте, что этот фрагмент хотел бы участвовать в заполнении меню опций, получив вызов onCreateOptionsMenu (Menu, MenuInflater) и связанные с ним методы.

  • Переопределите методPrepareOptionMenu в вашем классе фрагмента.

Подготовьте меню стандартных параметров экрана, которое будет отображаться. Это вызывается прямо перед отображением меню при каждом его показе. Вы можете использовать этот метод для эффективного включения / отключения элементов или, в противном случае, для динамического изменения содержимого.

Затем в этом методе попробуйте найти элементы меню по идентификатору и сделать их видимыми / невидимыми, включенными / отключенными, например:

 @Override public void onPrepareOptionsMenu(Menu menu) { menu.findItem(HERB_SPINNER_ID).setVisible(false).setEnabled(false); } 

Прочитайте больше

В моем случае у меня есть 2 фрагмента, у которых есть другой пункт меню.

На моем MainActivity:

 FragmentA fragmentA = new FragmentA(); fragmentA.setTargetFragment(fragmentA, 0); FragmentB fragmentB = new FragmentB(); fragmentB.setTargetFragment(fragmentB, 1); 

И FragmentA и FragmentB:

 @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if(hidden) { getTargetFragment().setMenuVisibility(false); }else{ getTargetFragment().setMenuVisibility(true); } } 

Это позволит отображать меню из фрагмента A, когда B уходит. Если он вернется из B в Старое меню из A, можно увидеть.

Ссылка: здесь