Appcompatv7 - v21 Навігаційний ящик не показує значок гамбургера


101

Я реалізую навігаційний ящик у стилі льодяника з останньою бібліотекою підтримки appcompat, але проблема полягає в тому, що піктограма гамбургерів ніколи не відображається. Відображається лише значок спини.

Це мій код діяльності

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

 }
}

Це файл моїх стилів

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

Файл макета

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

Навігаційний ящик, що показує кнопку назад

Навігаційний ящик, що показує кнопку назад

В обох випадках показана лише стрілка назад, я прочитав багато публікацій, але нібито нічого не змінило. Будь-яка допомога буде вдячна.

Відповіді:


148

Вам потрібно зателефонувати

mDrawerToggle.syncState();

2
Я здогадуюсь всередині onDrawerClosed () та onDrawerOpened ()
Пол Верест

14
Одразу після того, як ви ініціалізуєте своєActionBarDrawerToggle
Педро Олівейра

1
Привіт! Чи можемо ми показати піктограму Hamburger це без виклику mDrawerToggl.syncState(), насправді я показую ящик навігації як накладку на панелі інструментів, тому анімація не потрібна в моєму випадку.
Shajeel Afzal

1
Можливо, ваша проблема - це ще одна @AlexVPerl. Не потрібно брати участь у програмі, лише тому, що це не спрацювало для вас. Чорт, якщо я буду спростовувати всі відповіді, які для мене не працюють ....
Педро Олівейра,

1
@PedroOliveira Це не випадки використання кнопок голосування вгору / вниз?
AlexVPerl

19

Переконайтеся, що ви імпортуєте правильний перемикач ящика.

Коли я імпортував версію v4, у мене була стрілка (нижче).

import android.support.v4.app.ActionBarDrawerToggle;

Змінивши його на це (нижче, v7), виправлено мою проблему.

import android.support.v7.app.ActionBarDrawerToggle;

14

Переконайтеся, що ви телефонуєте

mDrawerToggle.syncState();

ПІСЛЯ дзвінка

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

чи можна, не встановлюючи панель інструментів як панель дій, показувати гамбургер, який можна малювати?
андроїд розробник

13

Під час використання ActionBarDrawerToggle ви повинні викликати його під час onPostCreate () та 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);
    }

І onOptionsItemSelectedтеж.
Браїс Габін

Не допоможе мені. Android 6.0
підписник

9

Оскільки мій NavigationDrawer розширював фрагмент, а не активність, я не зміг змінити postCreate. Нижче - те, що я зробив.

   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

Сподіваюся, це допомагає!


Може, розширити трохи про те, чому ви вважаєте, що це допоможе людині, яка запитує?
Мікаел Олсон

Вибачте, що вони хотіли відобразити піктограму гамбургерів, і я змінив її з наведеним вище кодом. Прочитайте коментарі поруч із кодом. Це може допомогти людям, які застрягли із значком спини на навігаційному ящику.
користувач2132226

Як би ви показали гамбургер, який можна намалювати на панелі інструментів, не роблячи панель інструментів як панель дій?
андроїд розробник

6

Не забудьте замінити метод onOptionsItemSelected і перевірити, чи натиснено ctionBarDrawerToggle, у цьому випадку поверніть істину, інакше діяльність буде завершена.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

3
return actionBarDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
Однолінійний

5

Ви можете просто скористатися цим:

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

видаліть код після mDrawerToggle.syncState () , і вам добре піти.
Ахмад Джаміль Аль Расід

3

Включаючи ActionBarDrawerToggle, обов'язково використовуйте метод публікації:

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

Це працювало для мене! Це, а також видалення вирішення, здійснене за допомогою setHomeAsUpIndicator(R.drawable.ic_menu/ic_back)цього, примушувало піктограму, яка робила вигляд при переключенні між фрагментом. Але після оновлення до нової піктограми анімованих гамбургерів це не справляється.
Jota

3

mDrawerToggle.syncState() не працював для мене, але я врешті-решт змусив його працювати:

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

Однак я не використовував Панель інструментів.


Цей рядок коду врятував мені день. Я перетворив код затемнення на студію Android, і раптом моя кнопка перемикання ящика автоматично перетворилася на стрілку. тепер він працює добре після додавання цього рядка коду. Дякую чимало @john Leehey
Хітеш Камані

3

У мене також з’явилася аналогічна проблема, в моєму випадку проблема полягала в тому, що при ініціюванні дії в панелі дій я не передав дійсний аргумент панелі інструментів (панель інструментів була ініціалізована пізніше), без належної ненульової панелі інструментів ActionBarToggle не зможе створити піктограму гамбургера.

actionBarToggle = ActionBarDrawerToggle(this, mDrawer, toolbar, 
R.string.drawer_open, R.string.drawer_close);

1

ви можете зателефонувати syncState () з програми onPostCreate своєї активності, щоб синхронізувати індикатор із станом пов’язаного DrawerLayout після того, як onRestoreInstanceState відбувся.

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

Також ActionBarDrawerToggle можна використовувати безпосередньо як DrawerLayout.DrawerListener, або якщо ви вже надаєте власного слухача, зателефонуйте до кожного із слухачів із власних методів.

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

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

1

Ящик навігації не відображався, натискаючи меню панелі дій. Це зафіксувало це для мене.

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


        return super.onOptionsItemSelected(item);
    }

1

Це працює для мене. Я розширив AppCompatActivity замість 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();

    }
};
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.