OnCreateOptionsMenu () en el fragmento que no reemplaza los menús de ActionBar
Estoy utilizando el NavigationDrawer en mi aplicación y reemplazo el fragmento al hacer clic en un elemento del cajón. Mi problema que tengo es que los elementos de menú en el ActionBar no se actualizan cuando cambio el fragmento.
He seguido este tutorial https://www.grokkingandroid.com/adding-action-items-from-within-fragments/ de cerca, pero todavía no funciona en mi aplicación.
- Desplazamiento de izquierda a derecha con el visor y el cajón de navegación
- Cambiar fragmento con el cajón de navegación de Android Studio predeterminado
- Añadir 2 listview en el cajón de navegación, sólo uno funciona
- Reemplazar el diseño de la barra de herramientas de acuerdo con el fragmento visualizado
- Cómo seleccionar el primer elemento en un cajón de navegación y abrir un fragmento en el inicio de la aplicación
Añadir algunos fragmentos de código de la actividad principal y uno de los fragmentos aquí. Lo que necesito es mostrar los otros elementos de menú del fragmento de formulario de contacto (R.menu.contactform_send_menu) cuando el fragmento inicial se reemplaza con ContactFormFragment.java.
public class MainActivity extends FragmentActivity implements ActionBar.OnNavigationListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setTitle(R.string.app_name); // Set up the action bar to show a dropdown list. ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); actionBar.setDisplayShowTitleEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); createNavigationDrawer(savedInstanceState); } private final int DRAWER_MAIN = 0; private final int DRAWER_CONTACT = 5; // update the main content by replacing fragments private void selectItem(int position) { Fragment fragment = null; Bundle args = new Bundle(); boolean isFragment = false; switch (position) { case DRAWER_MAIN: fragment = new WelcomeSectionFragment(); args.putString(WelcomeSectionFragment.ITEM_NAME, dataList.get(position).getItemName()); args.putInt(WelcomeSectionFragment.IMAGE_RESOURCE_ID, dataList.get(position).getImgResID()); getActionBar().setTitle(R.string.app_name); isFragment = true; break; case DRAWER_CONTACT: fragment = new ContactFormFragment(); args.putString(ContactFormFragment.ITEM_NAME, dataList.get(position).getItemName()); args.putInt(ContactFormFragment.IMAGE_RESOURCE_ID, dataList.get(position).getImgResID()); getActionBar().setTitle(R.string.contactform_title); isFragment = true; break; default: break; } if (isFragment) { fragment.setArguments(args); FragmentManager frgManager = getFragmentManager(); frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); mDrawerList.setItemChecked(position, true); setTitle(dataList.get(position).getItemName()); mDrawerLayout.closeDrawer(mDrawerList); } } }
y el fragmento:
public class ContactFormFragment extends Fragment { public ContactFormFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ca = getActivity(); Reachability.registerReachability(ca.getApplicationContext()); settings = ca.getSharedPreferences(Konstanten.PREFERENCES_FILE, 0); member = new Gson().fromJson(settings.getString(Konstanten.MEMBER_OBJECT, null), Member.class); latoFontLight = Tools.getFont(ca.getAssets(), "Lato-Light.ttf"); latoFontBold = Tools.getFont(ca.getAssets(), "Lato-Bold.ttf"); // Update action bar menu items? setHasOptionsMenu(true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Do something that differs the Activity's menu here super.onCreateOptionsMenu(menu, inflater); menu.clear(); if (Build.VERSION.SDK_INT >= 11) { // selectMenu(menu); inflater.inflate(R.menu.contactform_send_menu, menu); } } }
Al depurar puedo ver que setHasOptionsMenu (true); se llama en onCreate () y también entrar en el onCreateOptionsMenu () de ContactFormFragment.java. Simplemente no entiendo por qué la barra de acción mantiene sus elementos iniciales del menú y no los reemplaza. ¿Qué me estoy perdiendo?
Gracias por cualquier ayuda.
- Cómo agregar un separador de sección para el cajón de navegación en Android?
- Elementos de menú de la bandeja de navegación seleccionados dentro de diferentes grupos
- Administrar la barra de herramientas y el botón de retroceso del fragmento en android
- El cajón de navegación en android no está en pantalla completa
- No abra el cajón de navegación de forma predeterminada
- Adición de una imagen grande a un cajón de navegación (SlidingMenu libs) - ¿Cómo?
- Cambiar el título del encabezado de NavigationView
- Desactivar oscurecimiento oscuro en el cajón de navegación
Intente poner setHasOptionsMenu(true);
dentro de la onCreateView()
de su ChildFragment.java
no veo una en el código que publicó.
¡Lo tengo trabajando! El problema que tuve fue que he añadido un menú desplegable personalizado al fragmento principal. Así que cada vez que cambio el fragmento a través de la navegación del cajón manualmente tengo que eliminar ese menú desplegable y al volver al fragmento principal lo volveré a añadir.
Esto es lo que hice:
En la actividad principal:
MainActivity.java:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.signin_menu, menu); getMenuInflater().inflate(R.menu.clear_search_history_menu, menu); // Search // Associate searchable configuration with the SearchView getMenuInflater().inflate(R.menu.search_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); return super.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); getMenuInflater().inflate(R.menu.signin_menu, menu); getMenuInflater().inflate(R.menu.clear_search_history_menu, menu); // Search // Associate searchable configuration with the SearchView getMenuInflater().inflate(R.menu.search_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); // If the nav drawer is open, hide action items related to the content // view boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.search).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } // This is the selection of the drawer (stripped some code to keep it short) private void selectItem(int position) { Fragment fragment = null; Bundle args = new Bundle(); boolean isFragment = false; ActionBar actionBar = getActionBar(); switch (position) { case DRAWER_MAIN: fragment = new WelcomeSectionFragment(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); actionBar.setListNavigationCallbacks(new GameSystemsAdapter(getActionBarThemedContextCompat(), allSystemsPlusEmpty), this); actionBar.setTitle(R.string.app_name); isFragment = true; break; case DRAWER_FAVORITES: fragment = new FavoritesMainFragment(); // Remove System-Select Drop-Down actionBar.setListNavigationCallbacks(null, null); actionBar.setNavigationMode(0); actionBar.setTitle(R.string.favorites); isFragment = true; break; case DRAWER_TOP_MEMBERS: fragment = new TopMembersFragment(); // Remove System-Select Drop-Down actionBar.setListNavigationCallbacks(null, null); actionBar.setNavigationMode(0); actionBar.setTitle(R.string.top_members_top_helping); isFragment = true; break; default: break; } if (isFragment) { fragment.setArguments(args); FragmentManager frgManager = getFragmentManager(); frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); mDrawerList.setItemChecked(position, true); setTitle(dataList.get(position).getItemName()); mDrawerLayout.closeDrawer(mDrawerList); } }
y aquí la parte del (de los) fragmento (s):
ChildFragment.java
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); if (Build.VERSION.SDK_INT >= 11) { selectMenu(menu); } } @Override public void onPrepareOptionsMenu(Menu menu) { selectMenu(menu); } private void selectMenu(Menu menu) { parentActivity.getMenuInflater().inflate(R.menu.contactform_send_menu, menu); }
Si hay mejores soluciones, estoy muy interesado en sus ideas.
Hay dos casos a considerar:
- Desea que todos los elementos de acción provengan exclusivamente de fragmentos.
- También tiene elementos de acción que deben ser globales y se definen dentro de la actividad.
Comencemos con la opción 2, ya que es el caso más común.
Si tiene elementos específicos de fragmentos y elementos globales al mismo tiempo, no desea utilizar onCreateOptionsMenu()
dentro del fragmento. La razón es que parecería extraño – incluso si funcionaba. Las acciones de fragmento se añadirían justo después de crear el fragmento, mientras que los elementos globales se añadirían después de que el cajón se cerró (de forma predeterminada). Creo que a ningún usuario le gustaría eso.
Lo que podrías hacer para dejar que el fragmento decida qué elementos mostrar es crear una interfaz para todos los fragmentos para implementar. Esto podría definir un método que devolvería el ID del menú para que el menú se inflara o -1
si no se inflara un menú.
En el caso de la opción 1, sólo puedo asumir que clear()
el menú dentro de la actividad onCreateOptionsMenu()
. De lo contrario, no borraría las entradas de menú de los fragmentos. Así que acaba de deshacerse de la clear()
y todo debe estar bien.