I want to change the visibility of menu items of a fragment activity (abs) when ever I change the fragment in the activity. The fragments are SherlockListFragments.
The menu items I want to show/hide are spinners I create on menu creation:
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;
}
My logic for switching the fragments is:
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;
}
My first idea was to hold the menu object in a holder class and manipulate it there whenever I switch the fragment (in every case statement above).
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);
}
}
}
My problem is that there is no menu item with the given ID which are activity local constants. I get an NPE here. Does anybody have an idea how I can fix that? Is there a better way to change the menu on switching fragments?
Best regards Carsten
How do we hide the menu on toolbar in one fragment? When you click the show button to open a fragment, you can see the fragment menu items ordered before activity menu items. This is because of the menu item's android:orderInCategory attribute value. When you click the hide button to hide the fragment.
You can use Fragment. getView() . This returns the view of the container which contains the Fragment . On that view, you can call removeAllViews .
Use replace() to replace an existing fragment in a container with an instance of a new fragment class that you provide. Calling replace() is equivalent to calling remove() with a fragment in a container and adding a new fragment to that same container. transaction. commit();
Since all fragments are destroyed if the activity is destroyed, a simple answer could be calling getActivity(). isDestroyed() returning true if the activity is destroyed, therefore the fragment is destroyed.
In my case, I have 2 fragments that has a different menu item.
On my MainActivity:
FragmentA fragmentA = new FragmentA();
fragmentA.setTargetFragment(fragmentA, 0);
FragmentB fragmentB = new FragmentB();
fragmentB.setTargetFragment(fragmentB, 1);
and FragmentA and FragmentB has:
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(hidden) {
getTargetFragment().setMenuVisibility(false);
}else{
getTargetFragment().setMenuVisibility(true);
}
}
this will let menu from fragment A be visible when B is leaving. If it’s going back from B to A old menus from A can be visible.
Reference: here
Is there a better way to change the menu on switching fragments?
May be yes :).
In your fragment onCreate
, add this :
setHasOptionsMenu (true);
The doc :
Report that this fragment would like to participate in populating the options menu by receiving a call to onCreateOptionsMenu(Menu, MenuInflater) and related methods.
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.
Then, in this method, try to find your menu items by ID, and make them visible/unvisible, enabled/disabled, like this :
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(HERB_SPINNER_ID).setVisible(false).setEnabled(false);
}
Read More
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With