Appcompatv7 - szuflada nawigacji v21 nie wyświetla ikony hamburgera

101

Wdrażam szufladę nawigacji w stylu Lollipop z najnowszą biblioteką obsługującą appcompat, ale problem polega na tym, że ikona hamburgera nigdy nie jest wyświetlana. Wyświetlana jest tylko ikona powrotu.

To jest mój kod aktywności

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

 }
}

To jest mój plik stylów

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

Plik układu

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

Szuflada nawigacji pokazująca przycisk Wstecz

Szuflada nawigacji pokazująca przycisk Wstecz

W obu przypadkach wyświetlana jest tylko strzałka wstecz, przeczytałem wiele postów, ale wydaje się, że nic nie robi różnicy. Każda pomoc będzie mile widziana.

Ravi
źródło

Odpowiedzi:

148

Musisz zadzwonić

mDrawerToggle.syncState();
Pedro Oliveira
źródło
2
Myślę, że wewnątrz onDrawerClosed () i onDrawerOpened ()
Paul Verest
14
Zaraz po inicjalizacjiActionBarDrawerToggle
Pedro Oliveira,
1
Cześć! Czy możemy pokazać ikonę Hamburgera bez wywoływania mDrawerToggl.syncState(), w rzeczywistości pokazuję szufladę nawigacji jako nakładkę na pasku narzędzi, więc animacja nie jest wymagana w moim przypadku.
Shajeel Afzal
1
Być może twój problem jest inny @AlexVPerl. Nie musisz głosować negatywnie tylko dlatego, że to nie zadziałało. Do diabła, jeśli mam zamiar przegłosować wszystkie odpowiedzi, które nie działają dla mnie ....
Pedro Oliveira
1
@PedroOliveira Czy to nie przypadek użycia przycisków głosowania w górę / w dół?
AlexVPerl
19

Upewnij się, że importujesz właściwy przełącznik szuflady.

Kiedy importowałem wersję v4, miałem strzałkę (poniżej).

import android.support.v4.app.ActionBarDrawerToggle;

Zmiana tego na to (poniżej, v7) rozwiązała mój problem.

import android.support.v7.app.ActionBarDrawerToggle;
Donn Felker
źródło
14

Upewnij się, że dzwonisz

mDrawerToggle.syncState();

PO zadzwonieniu

getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
getSupportActionBar().setHomeButtonEnabled(true); 
Lukas Lechner
źródło
czy jest możliwe bez ustawiania paska narzędzi jako paska działań, aby pokazać rysowany hamburger?
programista android
13

Używając ActionBarDrawerToggle, musisz wywołać go podczas onPostCreate () i 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
źródło
I onOptionsItemSelectedteż.
Brais Gabin
Nie pomoże mi. Android 6.0
a_subscriber
9

Ponieważ mój NavigationDrawer rozszerzał fragment, a nie działanie, nie mogłem zastąpić postCreate. Poniżej przedstawiam to, co zrobiłem.

   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

Mam nadzieję, że to pomoże!

user2132226
źródło
Może rozwiń trochę, dlaczego uważasz, że to pomogłoby osobie, która pyta?
Mikael Ohlson
Przepraszam, że chcieli wyświetlić ikonę hamburgera, a sposób, w jaki ją zmieniłem, był za pomocą powyższego kodu. Przeczytaj komentarze obok kodu. Może to pomóc osobom, które utknęły z ikoną wstecz w szufladzie nawigacji.
user2132226
Jak pokazałbyś hamburgera do rysowania na pasku narzędzi, bez tworzenia paska narzędzi jako paska akcji?
programista Android
6

Nie zapomnij nadpisać metody onOptionsItemSelected i sprawdzić, czy kliknięto ctionBarDrawerToggle, w tym przypadku zwróć true, w przeciwnym razie działanie zostanie zakończone.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
Alberto Penas
źródło
3
Jedna linijka:return actionBarDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
gregschlom
5

Możesz po prostu użyć tego:

// 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
źródło
usuń kod po mDrawerToggle.syncState () i gotowe.
Ahmad Jamil Al Rasyid
3

Włączając ActionBarDrawerToggle, upewnij się, że używasz metody post:

mDrawerLayout.post(new Runnable() {
   @Override
   public void run() {
       mDrawerToggle.syncState();
   }
});
user3248601
źródło
To zadziałało dla mnie! To, a także usunięcie obejścia wykonanego za pomocą setHomeAsUpIndicator(R.drawable.ic_menu/ic_back)tego, wymuszało ikonę, która była udawana podczas przełączania się między fragmentami. Ale po aktualizacji do nowej animowanej ikony burgera, to nie działa.
Jota
3

mDrawerToggle.syncState() nie zadziałało dla mnie, ale w końcu udało mi się to:

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

Nie korzystałem jednak z paska narzędzi.

John Leehey
źródło
Ta linia kodu uratowała mi dzień. Przekonwertowałem mój kod zaćmienia na Android Studio i nagle mój przycisk przełączania szuflady automatycznie przekształcił się w strzałkę. teraz działa dobrze po dodaniu tego wiersza kodu. Wielkie dzięki @john Leehey
Kamani
3

Miałem również podobny problem, w moim przypadku problem polegał na tym, że podczas inicjowania actionbartoggle nie przekazywałem prawidłowego argumentu paska narzędzi (pasek narzędzi został zainicjowany później), bez odpowiedniego, niezerowego paska narzędzi, ActionBarToggle nie utworzy ikony hamburgera.

actionBarToggle = ActionBarDrawerToggle(this, mDrawer, toolbar, 
R.string.drawer_open, R.string.drawer_close);
Shamsul Arefin Sajib
źródło
1

możesz wywołać syncState () z onPostCreate swojego działania, aby zsynchronizować wskaźnik ze stanem połączonego DrawerLayout po wystąpieniu onRestoreInstanceState.

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

Ponadto ActionBarDrawerToggle może być używane bezpośrednio jako DrawerLayout.DrawerListener lub, jeśli już udostępniasz własny detektor, wywołaj każdą z metod listenera z własnej.

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

    mDrawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mDrawerToggle.syncState();
        }
    });
Jorge Casariego
źródło
1

Szuflada nawigacji nie była wyświetlana po kliknięciu menu paska działań. To naprawiło to dla mnie.

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


        return super.onOptionsItemSelected(item);
    }
Ronny Kibet
źródło
1

To działa dla mnie. Rozszerzyłem AppCompatActivity zamiast 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
źródło