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ú:
- Botón de selección de Android MenuItem
- Disposición personalizada de MenuItem de Android
- Cómo utilizar los elementos de la barra de herramientas con Viewpager + Fragmentos
- Android: muestra el menú de varias actividades
- IllegalArgumentException Tipo de elemento de carga útil no válido - Con ActionBarCompat
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
- Android: Obtener una vista Referencia a un elemento de menú
- Android ActionBar MenuItem LowerCase
- Tableta de Gmail como elementos de Actionbar
- App Crash al intentar cambiar textsize en textView haciendo clic en el botón
- Android añadiendo un submenú a un menuItem, donde es addSubMenu ()?
- ¿Cómo puedo establecer la visibilidad de un elemento de ActionBar en fragmento diferente
- Configuración de la descripción del contenido del menú de opciones android Talkback
- Iniciar animación en carga de página, detener en página cargada
¿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í
- Android 5.0 Lollipop: setColorFilter "filtra" en otros botones
- GetSize () no es compatible con versiones anteriores de Android OS, getWidth () / getHeight () obsoleto