Appcompatv7 - Le tiroir de navigation v21 n'affiche pas l'icône de hamburger

101

J'implémente le tiroir de navigation de style lollipop avec la dernière bibliothèque de support appcompat mais le problème est que l'icône hamburger n'est jamais affichée. Seule l'icône de retour est affichée.

Ceci est mon code d'activité

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

 }
}

Ceci est mon fichier de styles

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

Le fichier de mise en page

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

Tiroir de navigation montrant le bouton de retour

Tiroir de navigation montrant le bouton de retour

Dans les deux cas, seule la flèche arrière est affichée, j'ai lu de nombreux articles mais rien ne semble faire de différence. Toute aide serait appréciée.

Ravi
la source

Réponses:

148

Vous devez appeler

mDrawerToggle.syncState();
Pedro Oliveira
la source
2
Je suppose que dans onDrawerClosed () et onDrawerOpened ()
Paul Verest
14
Juste après avoir initialisé votreActionBarDrawerToggle
Pedro Oliveira
1
Salut! Pouvons-nous afficher l'icône Hamburger sans appeler mDrawerToggl.syncState(), en fait, je montre le tiroir de navigation en superposition sur la barre d'outils, donc l'animation n'est pas requise dans mon cas.
Shajeel Afzal
1
Le peut-être que votre problème est un autre @AlexVPerl. Inutile de voter contre parce que cela n'a pas fonctionné pour vous. Enfer, si je vais contrevoter toutes les réponses qui ne fonctionnent pas pour moi ....
Pedro Oliveira
1
@PedroOliveira N'est-ce pas le cas d'utilisation des boutons de vote haut / bas?
AlexVPerl
19

Assurez-vous que vous importez la bascule de tiroir appropriée.

Lorsque j'ai importé la version v4, j'avais la flèche (ci-dessous).

import android.support.v4.app.ActionBarDrawerToggle;

Le changer en ceci (ci-dessous, v7) a résolu mon problème.

import android.support.v7.app.ActionBarDrawerToggle;
Donn Felker
la source
14

Assurez-vous d'appeler

mDrawerToggle.syncState();

APRÈS avoir appelé

getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
getSupportActionBar().setHomeButtonEnabled(true); 
Lukas Lechner
la source
est-il possible sans définir la barre d'outils comme barre d'action, d'afficher le hamburger dessiné?
développeur android
13

Lorsque vous utilisez ActionBarDrawerToggle, vous devez l'appeler pendant onPostCreate () et 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
la source
Et onOptionsItemSelectedaussi.
Brais Gabin
Pas de secours pour moi. Android 6.0
a_subscriber
9

Étant donné que mon NavigationDrawer étendait un fragment et non une activité, je n'ai pas pu remplacer postCreate. Voici ce que j'ai fait.

   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

J'espère que ça aide!

user2132226
la source
Peut-être expliquez-vous pourquoi vous pensez que cela aiderait la personne qui pose la question?
Mikael Ohlson
Désolé, ils voulaient que l'icône du hamburger soit affichée et la façon dont je l'ai modifiée était avec le code ci-dessus. Veuillez lire les commentaires à côté du code. Cela pourrait aider les personnes qui restent bloquées avec l'icône de retour dans le tiroir de navigation.
user2132226
Comment afficheriez-vous le hamburger dessinable dans la barre d'outils, sans faire de la barre d'outils une barre d'action?
développeur android
6

N'oubliez pas de remplacer la méthode onOptionsItemSelected et de vérifier si ctionBarDrawerToggle a été cliqué, dans ce cas, retournez true sinon l'activité sera terminée.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
Alberto Penas
la source
3
One-liner:return actionBarDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
gregschlom
5

Vous pouvez simplement utiliser ceci:

// 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
la source
supprimez le code après mDrawerToggle.syncState () , et vous êtes prêt à partir.
Ahmad Jamil Al Rasyid
3

Lorsque vous incluez ActionBarDrawerToggle, assurez-vous d'utiliser la méthode de publication:

mDrawerLayout.post(new Runnable() {
   @Override
   public void run() {
       mDrawerToggle.syncState();
   }
});
user3248601
la source
Cela a fonctionné pour moi! Cela et également la suppression d'une solution de contournement effectuée en utilisant setHomeAsUpIndicator(R.drawable.ic_menu/ic_back)qui forçait l'icône qui était prétendue lors du passage d'un fragment à l'autre. Mais après avoir été mis à jour avec la nouvelle icône animée de hamburger, cela ne fait pas le travail.
Jota
3

mDrawerToggle.syncState() n'a pas fonctionné pour moi, mais je l'ai finalement réussi à travailler avec:

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

Je n'utilisais cependant pas de barre d'outils.

John Leehey
la source
Cette ligne de code m'a sauvé la journée. J'ai converti mon code d'éclipse en studio Android et tout d'un coup mon bouton bascule de tiroir s'est automatiquement converti en flèche. maintenant cela fonctionne correctement après avoir ajouté cette ligne de code. Merci beaucoup @john Leehey
Hitesh Kamani
3

J'ai également eu un problème similaire, dans mon cas, le problème était que, lors du lancement de l'actionbartoggle, je ne transmettais pas d'argument de barre d'outils valide (la barre d'outils a été initialisée plus tard), sans une barre d'outils appropriée et non nulle, ActionBarToggle ne parviendra pas à créer une icône de hamburger.

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

vous pouvez appeler syncState () à partir de onPostCreate de votre activité pour synchroniser l'indicateur avec l'état du DrawerLayout lié après que onRestoreInstanceState s'est produit.

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

ActionBarDrawerToggle peut également être utilisé directement comme DrawerLayout.DrawerListener, ou si vous fournissez déjà votre propre écouteur, appelez chacune des méthodes d'écoute à partir de la vôtre.

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

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

Le tiroir de navigation ne s'affichait pas lorsque vous cliquiez sur le menu de la barre d'actions. Cela a réglé le problème pour moi.

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


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

Cela fonctionne pour moi. J'ai étendu AppCompatActivity au lieu d'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
la source