Ocultar los MenuItems de la barra de acción cuando el cajón de navegación se desliza por cualquier cantidad
Estoy tratando de implementar un Cajón de navegación que oculta los elementos de menú en la barra de acción cada vez que se abre el cajón.
Estoy siguiendo la documentación de Google, sin embargo, su código no produce el comportamiento esperado.
Http://developer.android.com/training/implementing-navigation/nav-drawer.html
Usando este código, los elementos del menú se ocultan cuando el cajón se abre completamente, y se muestran cuando el cajón se vuelve completamente cerrado.
Sin embargo, la aplicación Gmail se comporta de manera diferente. Los elementos del menú se ocultan tan pronto como el cajón se abre por cualquier cantidad. Este es el comportamiento que quiero. ¿Alguien sabe cómo lograrlo?
Gracias!
7 answers
¿has probado esto:
- Use
invalidateOptionsMenu()
cada vez que alterne el cajón de navegación, midiendo el desplazamiento deslizante. -
Itere sobre cada elemento del menú en
onPrepareOptionsMenu(Menu menu)
y escóndalo.@Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view boolean drawerOpen = shouldGoInvisible; hideMenuItems(menu, !drawerOpen); return super.onPrepareOptionsMenu(menu); } private void hideMenuItems(Menu menu, boolean visible) { for(int i = 0; i < menu.size(); i++){ menu.getItem(i).setVisible(visible); } }
Detectando cuánto se ha deslizado el cajón de navegación:
mDrawerLayout.setDrawerListener(new DrawerListener(){
float mPreviousOffset = 0f;
@Override
public void onDrawerClosed(View arg0) {
super.onDrawerClosed(arg0);
shouldGoInvisible = false;
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
@Override
public void onDrawerOpened(View arg0) {
super.onDrawerOpened(arg0);
shouldGoInvisible = true;
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
@Override
public void onDrawerSlide(View arg0, float slideOffset) {
super.onDrawerSlide(arg0, slideOffset);
if(slideOffset > mPreviousOffset && !shouldGoInvisible){
shouldGoInvisible = true;
invalidateOptionsMenu();
}else if(mPreviousOffset > slideOffset && slideOffset < 0.5f && shouldGoInvisible){
shouldGoInvisible = false;
invalidateOptionsMenu();
}
mPreviousOffset = slideOffset;
}
@Override
public void onDrawerStateChanged(int arg0) {
// or use states of the drawer to hide/show the items
}});
Nota: shouldGoInvisible
es un campo de clase.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-27 22:39:01
Si desea anular la barra de acciones tan pronto como el cajón entre en la pantalla y restaurar la barra de acciones en el momento en que el cajón ya no sea visible (exactamente cómo se comporta Gmail a partir del 20 de marzo de 2014), puede usar el siguiente código:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
boolean isOpened = mDrawerLayout.isDrawerOpen(mDrawerList);
boolean isVisible = mDrawerLayout.isDrawerVisible(mDrawerList);
if (!isOpened && !isVisible) {
if (newState == DrawerLayout.STATE_IDLE) {
// drawer just hid completely
restoreActionBar();
} else {
// } else if (newState == DrawerLayout.STATE_SETTLING) {
// drawer just entered screen
overrideActionBar();
}
}
}
private void restoreActionBar() {
getSupportActionBar().setTitle(mTitle);
supportInvalidateOptionsMenu();
}
private void overrideActionBar() {
getSupportActionBar().setTitle(mDrawerTitle);
supportInvalidateOptionsMenu();
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
Modifique los métodos restoreActionBar()
y overrideActionBar()
de acuerdo con sus necesidades.
No hay necesidad de distinguir entre los golpes y el botón de inicio y no hay necesidad de medir las longitudes de golpe.
Variación
Si no desea hacer referencia a la vista de lista de cajones, use el siguiente código en su lugar:
boolean isOpened = mDrawerLayout.isDrawerOpen(GravityCompat.START);
boolean isVisible = mDrawerLayout.isDrawerVisible(GravityCompat.START);
Es posible que desee usar GravityCompat.END
en su lugar, dependiendo de lo que haya especificado en el diseño XML.
Editar-acerca de las acciones
El ejemplo anterior no oculta los elementos de la barra de acciones relevantes para el contenido debajo del cajón de navegación. Para hacerlo o mostrar un conjunto diferente de iconos cuando el cajón está visible, debe realizar un seguimiento de si el cajón se abre o se cierra manualmente.
Además del código anterior declare private boolean mDrawerVisible = false
con la función de guardar / restaurar adecuada manejo estatal.
Luego modifique mDrawerToggle
los métodos internos de la siguiente manera:
private void restoreActionBar() {
getSupportActionBar().setTitle(mTitle);
mDrawerVisible = false;
supportInvalidateOptionsMenu();
}
private void overrideActionBar() {
getSupportActionBar().setTitle(mDrawerTitle);
mDrawerVisible = true;
supportInvalidateOptionsMenu();
}
Finalmente en onCreateOptionsMenu
inflar diferentes recursos de menú o en onPrepareOptionsMenu
mostrar/ocultar diferentes acciones basadas en el valor de mDrawerVisible
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-23 17:49:24
Estoy medio de acuerdo con Nikola, pero basta con actualizar los iconos cuando el estado del cajón tiene
Crear una variable global para realizar un seguimiento del estado del cajón:
private int mDrawerState;
Establecer un nuevo DrawerListener:
mDrawerLayout.setDrawerListener(new DrawerListener() {
@Override
public void onDrawerStateChanged(int state) {
mDrawerState = state;
invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View view, float slide) {
// TODO Auto-generated method stub
}
@Override
public void onDrawerOpened(View view) {
// TODO Auto-generated method stub
}
@Override
public void onDrawerClosed(View view) {
// TODO Auto-generated method stub
}
});
Actualizar la visibilidad del menú:
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawer);
for(int i=0;i<menu.size();i++){
// If the drawer is moving / settling or open do not draw the icons
menu.getItem(i).setVisible(mDrawerState!=DrawerLayout.STATE_DRAGGING &&
mDrawerState!=DrawerLayout.STATE_SETTLING && !drawerOpen);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-08 22:30:34
Tengo una mejor solución para esta pregunta:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (navigationDrawerFragment.isDrawerOpen()) {
menu.clear();
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!navigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
showLocalContextActionBar();
return false;
}
return super.onCreateOptionsMenu(menu);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-25 20:59:06
Si desea ocultar todos los elementos del menú, simplemente use:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return showActionBarMenu; // boolean value, set it in drawer listeners as class variable
}
Entonces usted no necesita visible de cada elemento de menú.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 06:06:36
Tomé la respuesta de @Laurence Dawson y la simplifiqué un poco. Esta solución no requiere que se use ningún miembro de la clase.
Ejecuta este código durante onCreate()
:
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View view, float v) {
invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
}
@Override
public void onDrawerOpened(View view) {}
@Override
public void onDrawerStateChanged(int state) {}
});
Y anula este método:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
boolean actionsVisibility = !drawerLayout.isDrawerVisible(Gravity.START);
for(int i=0;i<menu.size();i++){
menu.getItem(i).setVisible(actionsVisibility);
}
return super.onPrepareOptionsMenu(menu);
}
Algunas notas:
- La implementación anterior asume que la vista asociada con NavigationDrawer tiene su
layout_gravity
establecido enstart
en XML. - No relacionado con la pregunta de OP, pero molesto: parece haber algún tipo de error que hace que el cajón atascado en el camino. Si observa este comportamiento, aquí está la solución: Error en el cajón de navegación de Android usando el ejemplo
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:00:42
Tengo un código diferente pero la misma solución:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
hideMenuItems(menu, !mShouldGoInvisible);
return super.onCreateOptionsMenu(menu);
}
private void hideMenuItems(Menu menu, boolean visible){
for(int i = 0; i < menu.size(); i++){
menu.getItem(i).setVisible(visible);
}
}
Y
@Override
public void onNavigationDrawerListener(boolean opened, int position) {
if (opened){
mShouldGoInvisible = true;
invalidateOptionsMenu();
} else {
mShouldGoInvisible = false;
invalidateOptionsMenu();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-23 15:21:23