Android: Cambiar la visibilidad de los elementos del menú con un fragmento cambiante

Quiero cambiar la visibilidad de elementos de menú de una actividad de fragmento (abs) cuando cambie el fragmento en la actividad. Los fragmentos son SherlockListFragments.

Los elementos de menú que quiero mostrar / ocultar son los hilanderos que creo en la creación del menú:

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

Mi lógica para conmutar los fragmentos es:

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

Mi primera idea fue mantener el objeto de menú en una clase de titular y manipular allí siempre que cambiar el fragmento (en cada caso la declaración anterior).

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

Mi problema es que no hay ningún elemento de menú con el ID dado que son constantes locales de actividad. Tengo una NPE aquí. ¿Alguien tiene una idea de cómo puedo arreglar eso? ¿Hay una mejor manera de cambiar el menú de conmutación de fragmentos?

Saludos cordiales Carsten

¿Hay una mejor manera de cambiar el menú de conmutación de fragmentos?

Tal vez sí :).

  • En su fragmento onCreate , añada esto:

    SetHasOptionsMenu (true);

El documento :

Informe que este fragmento desea participar en el menú de opciones al recibir una llamada a onCreateOptionsMenu (Menu, MenuInflater) y métodos relacionados.

  • Anule el método onPrepareOptionMenu en la clase de fragmento.

Prepare el menú de opciones estándar de la pantalla para que se muestre. Esto se llama justo antes de que se muestre el menú, cada vez que se muestra. Puede utilizar este método para activar / desactivar elementos de forma eficiente o modificar dinámicamente el contenido.

A continuación, en este método, intente encontrar los elementos de menú por ID y hágalos visibles / no visibles, activados / desactivados, de la siguiente manera:

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

Lee mas

En mi caso, tengo 2 fragmentos que tiene un elemento de menú diferente.

En mi MainActivity:

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

Y FragmentA y FragmentB tiene:

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

Esto permitirá que el menú del fragmento A sea visible cuando B está saliendo. Si vuelve de B a A los viejos menús de A pueden ser visibles.

Referencia: aquí

  • ActionBarSherlock menú de texto del panel de menú duro
  • Elemento de menú Android 4.3 showAsAction = "siempre" ignorado
  • Mostrando el diseño personalizado en el elemento de menú desplegable de desbordamiento? Androide
  • ¿Qué debo pasar por la raíz al inflar una presentación para utilizarla en ActionView de MenuItem?
  • Agregar dinámicamente elemento de acción en la barra de acción
  • ¿Qué relleno, margen y tamaño debo utilizar para un diseño personalizado MenuItem?
  • ANDROID: Habilitar y deshabilitar MenuItem en el esquema de la actividad del cajón de navegación
  • El estado marcado de MenuItem no se muestra correctamente por su icono
  • Android: Vista personalizada de un elemento de menú
  • onPrepareOptionsMenu Duplica el elemento en ActionBar
  • Iconos translúcidos en ActionBar cuando está inhabilitado: ¿sólo en mi teléfono?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.