Appcompatv7: el cajón de navegación v21 no muestra el icono de hamburguesa

101

Estoy implementando el cajón de navegación estilo lollipop con la última biblioteca de soporte de appcompat, pero el problema es que el icono de hamburguesa nunca se muestra. Solo se muestra el icono de retroceso.

Este es mi código de actividad

import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.View;

public class Home extends ActionBarActivity {

private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    initViews();
}


private void initViews(){

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);


    toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
    setSupportActionBar(toolbar);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,toolbar ,  R.string.drawer_open, R.string.drawer_close) { 

        /** Called when a drawer has settled in a completely closed state. */ 
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            //getActionBar().setTitle(mTitle);
            //invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        } 

        /** Called when a drawer has settled in a completely open state. */ 
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            //getActionBar().setTitle(mDrawerTitle);
            //invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        } 
    }; 


    // Set the drawer toggle as the DrawerListener 
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    getSupportActionBar().setHomeButtonEnabled(true); 

 }
}

Este es mi archivo de estilos

 <resources>
 <!-- Application theme. -->
<style name="Theme.Test" parent="@style/Theme.AppCompat.Light">

    <!-- customize the color palette -->
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="windowActionBar">false</item>
    <item name="drawerArrowStyle">@style/Theme.Test.DrawerArrowStyle</item>
</style>

<style name="Theme.Test.DrawerArrowStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@android:color/white</item>
</style>

El archivo de diseño

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:layout_below="@+id/toolbar">

    <!-- The main content view -->

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>

</RelativeLayout>

Cajón de navegación que muestra el botón Atrás

Cajón de navegación que muestra el botón Atrás

En ambos casos, solo se muestra la flecha hacia atrás, he leído muchas publicaciones pero nada parece marcar la diferencia. Cualquier ayuda sería apreciada.

Ravi
fuente

Respuestas:

148

Necesitas llamar

mDrawerToggle.syncState();
Pedro Oliveira
fuente
2
Supongo que dentro de onDrawerClosed () y onDrawerOpened ()
Paul Verest
14
Justo después de inicializar suActionBarDrawerToggle
Pedro Oliveira
1
¡Hola! ¿Podemos mostrar el icono de Hamburger sin llamar? En mDrawerToggl.syncState()realidad, estoy mostrando el cajón de navegación superpuesto en la barra de herramientas, por lo que la animación no es necesaria en mi caso.
Shajeel Afzal
1
Quizás tu problema sea otro @AlexVPerl. No hay necesidad de votar en contra solo porque no funcionó para usted. Demonios, si voy a rechazar todas las respuestas que no funcionan para mí ...
Pedro Oliveira
1
@PedroOliveira ¿No es ese el caso de uso de los botones de voto hacia arriba / abajo?
AlexVPerl
19

Asegúrese de que está importando la palanca de cajón correcta.

Cuando importé la versión v4, tenía la flecha (abajo).

import android.support.v4.app.ActionBarDrawerToggle;

Cambiarlo a esto (a continuación, v7) solucionó mi problema.

import android.support.v7.app.ActionBarDrawerToggle;
Donn Felker
fuente
14

Asegúrate de llamar

mDrawerToggle.syncState();

DESPUÉS de llamar

getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
getSupportActionBar().setHomeButtonEnabled(true); 
Lukas Lechner
fuente
¿Es posible sin configurar la barra de herramientas como barra de acción, para mostrar la hamburguesa dibujable?
desarrollador de Android
13

Cuando use ActionBarDrawerToggle, debe llamarlo durante onPostCreate () y onConfigurationChanged ()

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
Sathesh
fuente
Y onOptionsItemSelectedtambien.
Brais Gabin
No me ayuda. Android 6.0
a_subscriber
9

Dado que mi NavigationDrawer estaba extendiendo un Fragmento, no una Actividad, no pude anular postCreate. Lo siguiente es lo que hice.

   ActionBar actionBar = getActionBar();
   actionBar.setDisplayHomeAsUpEnabled(true); // this sets the button to the    back icon
   actionBar.setHomeButtonEnabled(true); // makes it clickable
   actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer);// set your own icon

¡Espero eso ayude!

usuario2132226
fuente
Tal vez expanda un poco por qué cree que esto ayudaría a la persona que pregunta.
Mikael Ohlson
Lo siento, querían que se mostrara el icono de la hamburguesa y la forma en que lo cambié fue con el código anterior. Lea los comentarios al lado del código. Esto podría ayudar a las personas que se quedan atascadas con el icono de retroceso en el panel de navegación.
user2132226
¿Cómo mostraría la hamburguesa dibujable en la barra de herramientas, sin convertirla en barra de acción?
desarrollador de Android
6

No olvide anular el método onOptionsItemSelected y verificar si se hizo clic en ctionBarDrawerToggle, en este caso, devuelva verdadero, de lo contrario, la actividad finalizará.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
Alberto Peñas
fuente
3
One-liner:return actionBarDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
gregschlom
5

Simplemente puede usar esto:

// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
    @Override
    public void run() {
        mDrawerToggle.syncState();
        getActionBar().setHomeAsUpIndicator(R.drawable.ic_drawer);
    }
});
RobotCharlie
fuente
elimine el código después de mDrawerToggle.syncState () , y listo.
Ahmad Jamil Al Rasyid
3

Mientras incluye ActionBarDrawerToggle, asegúrese de utilizar el método de publicación:

mDrawerLayout.post(new Runnable() {
   @Override
   public void run() {
       mDrawerToggle.syncState();
   }
});
usuario3248601
fuente
¡Esto funcionó para mí! Eso y también eliminar una solución alternativa realizada al usar setHomeAsUpIndicator(R.drawable.ic_menu/ic_back)eso fue forzar el ícono que se pretendía al cambiar entre fragmentos. Pero después de actualizarse al nuevo ícono de hamburguesa animado, eso no funciona.
Jota
3

mDrawerToggle.syncState() no funcionó para mí, pero finalmente logré que funcionara con:

getSupportActionBar().setHomeAsUpIndicator(R.drawable.hamburger_icon);

Sin embargo, no estaba usando una barra de herramientas.

John Leehey
fuente
Esta línea de código me salvó el día. He convertido mi código de eclipse a Android Studio y, de repente, el botón de alternancia de mi cajón se convirtió automáticamente en una flecha. ahora está funcionando bien después de agregar esta línea de código. Muchas gracias @john Leehey
Hitesh Kamani
3

También tuve un problema similar, en mi caso el problema fue que, al iniciar actionbartoggle, no pasaba un argumento válido de la barra de herramientas (la barra de herramientas se inicializó más tarde), sin una barra de herramientas adecuada y no nula, ActionBarToggle no podrá crear un icono de hamburguesa.

actionBarToggle = ActionBarDrawerToggle(this, mDrawer, toolbar, 
R.string.drawer_open, R.string.drawer_close);
Shamsul Arefin Sajib
fuente
1

puede llamar a syncState () desde onPostCreate de su actividad para sincronizar el indicador con el estado del DrawerLayout vinculado después de que se haya producido onRestoreInstanceState.

@Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

Además, ActionBarDrawerToggle se puede usar directamente como DrawerLayout.DrawerListener, o si ya está proporcionando su propio oyente, llame a cada uno de los métodos de escucha desde el suyo.

private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
  .
  .
  .
  .
mDrawerLayout.setDrawerListener(mDrawerToggle);

    mDrawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mDrawerToggle.syncState();
        }
    });
Jorge Casariego
fuente
1

El cajón de navegación no se mostraba al hacer clic en el menú de la barra de acciones. Esto me lo arregló.

   @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
      //add your switch statement


        return super.onOptionsItemSelected(item);
    }
Ronny Kibet
fuente
1

Esto funciona para mi. He extendido AppCompatActivity en lugar de ActionBarActivity.

mActionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,null, R.string.drawer_opened, R.string.drawer_closed) {
    @Override
    public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        if( getSupportActionBar()!= null)
        getSupportActionBar().setTitle(R.string.drawer_opened);
        mActionBarDrawerToggle.syncState();
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        if(getSupportActionBar() != null)
            getSupportActionBar().setTitle(R.string.drawer_closed);
            mActionBarDrawerToggle.syncState();

    }
};
Mahen
fuente