Панель инструментов Android + ActionBarDrawerToggle не меняется на стрелку

Я борюсь с панелью инструментов и ящиком. Я пытаюсь сделать переключатель гамбургера стрелкой, когда я добавляю новый фрагмент в backstack, но нет никакого способа сделать это.

Может быть, я что-то упустил, но не смог найти способ. У кого-то была такая же проблема?

Это заявление:

mDrawerToggle = new ActionBarDrawerToggle( getActivityCompat(), /* host Activity */ mDrawerLayout, /* DrawerLayout object */ ((BaseActivity) getActivityCompat()).getToolbar(), R.string.navigation_drawer_open, /* "open drawer" description for accessibility */ R.string.navigation_drawer_close /* "close drawer" description for accessibility */ ) 

Это функция, которую я вызываю, когда фрагмент добавляется в задний стек

 public void setToggleState(boolean isEnabled) { if (mDrawerLayout == null) return; if (isEnabled) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); } mDrawerToggle.syncState(); } 

Я думаю, все, что вам нужно сделать, это удалить третий аргумент. Таким образом:

 mDrawerToggle = new ActionBarDrawerToggle( getActivityCompat(), /* host Activity */ mDrawerLayout, /* DrawerLayout object */ // ((BaseActivity) getActivityCompat()).getToolbar(), <== delete this argument R.string.navigation_drawer_open, /* "open drawer" description for accessibility */ R.string.navigation_drawer_close /* "close drawer" description for accessibility */ ); 

Пусть это поможет.

У меня такая же проблема. Мое решение было так:

Убедитесь, что ваша активность реализует onBackStackChangedListener. В ваших действиях «onCreate» я установил прослушиватель backstack, и я настроил панель инструментов

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFm = getFragmentManager(); mFm.addOnBackStackChangedListener(this); // Setup toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbar.setVisibility(View.VISIBLE); setSupportActionBar(mToolbar); // Setup drawer toggle mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.menu_open, R.string.menu_close); mDrawerLayout.setDrawerListener(mDrawerToggle); getSupportActionBar().setHomeButtonEnabled(true); mDrawerToggle.syncState(); // Setup initial fragment if (savedInstanceState == null) { mCurrentFragment = DashboardFragment.newInstance(); mFm.beginTransaction().add(CONTAINER_ID, mCurrentFragment).commit(); } } 

Также не забудьте установить:

 @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } 

Теперь волшебство происходит в onBackStackChanged (). Установка для параметра setDrawerIndicatorEnabled значения true для самого верхнего фрагмента и setDisplayHomeAsUpEnabled как false для этого фрагмента. Обратный для других. Мне также пришлось вызвать syncState, иначе гамбургер не появится снова:

 @Override public void onBackStackChanged() { mDrawerToggle.setDrawerIndicatorEnabled(mFm.getBackStackEntryCount() == 0); getSupportActionBar().setDisplayHomeAsUpEnabled(mFm.getBackStackEntryCount() > 0); mDrawerToggle.syncState(); } 

Я достиг этого, используя следующий макет: я использовал ActionBarDrawerToggle v7 Drawer.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.toolbar.Drawer" > <include android:id="@+id/tool1" layout="@layout/toolbar" /> <android.support.v4.widget.DrawerLayout android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/tool1" > <FrameLayout android:id="@+id/mainContent" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout> <!-- Nav drawer --> <ListView android:id="@+id/drawerList" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="left" android:background="@android:color/white" android:divider="@android:color/white" android:dividerHeight="8dp" android:drawSelectorOnTop="true" android:headerDividersEnabled="true" /> </android.support.v4.widget.DrawerLayout> </RelativeLayout> 

toolbar.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app1="http://schemas.android.com/apk/res/com.example.toolbar" android:id="@+id/my_awesome_toolbar" android:layout_width="fill_parent" android:layout_height="75dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" app1:popupTheme="@style/ThemeOverlay.AppCompat.Light" app1:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" > </android.support.v7.widget.Toolbar> 

Drawer.java

Пакет com.example.toolbar;

 import android.content.res.Configuration; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; 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.Gravity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; public class Drawer extends ActionBarActivity { ActionBarDrawerToggle mDrawerToggle; private String[] days; ArrayAdapter<String> adapter; private ListView mDrawerList; DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.drawer); days = new String[] { "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" }; adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, days); mDrawerList = (ListView) findViewById(R.id.drawerList); mDrawerList.setAdapter(adapter); mDrawerList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub Fragment fragment = new MyFragment(); Bundle args = new Bundle(); args.putString(MyFragment.ARG_PLANET_NUMBER, days[position]); // args.putInt(MyFragment.ARG_PLANET_NUMBER, position); fragment.setArguments(args); FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.mainContent, fragment).commit(); } }); Toolbar toolbar = (Toolbar) findViewById(R.id.tool1); setSupportActionBar(toolbar); toolbar.setTitle("ToolBar Demo"); toolbar.setLogo(R.drawable.ic_launcher); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer) { @Override public void onDrawerSlide(View drawerView, float slideOffset) { // TODO Auto-generated method stub super.onDrawerSlide(drawerView, slideOffset); } /** Called when a drawer has settled in a completely closed state. */ @Override public void onDrawerClosed(View view) { super.onDrawerClosed(view); getSupportActionBar().setTitle("hello"); } /** Called when a drawer has settled in a completely open state. */ @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getSupportActionBar().setTitle("hi"); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); // getSupportActionBar().setDisplayHomeAsUpEnabled(true); //<---- added // getSupportActionBar().setHomeButtonEnabled(true); //<---- added } @Override public boolean onOptionsItemSelected(MenuItem item) { // <---- added if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override protected void onPostCreate(Bundle savedInstanceState) { // <---- added super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); // important statetment for drawer to // identify // its state } @Override public void onConfigurationChanged(Configuration newConfig) { // <---- added super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public void onBackPressed() { if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) { // <---- // added mDrawerLayout.closeDrawers(); return; } super.onBackPressed(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 

@ В большинстве случаев ответ Хаты часто встречается.

Но на самом деле, вы не ошиблись, используя панель инструментов в качестве аргумента для конструктора ActionBarDrawerToggle(...) .

Конечно, нет смысла делать это, если вы используете Toolbar AppCompatActivity , используя, скажем, тему Theme.AppCompat.Light root. Даже если вы хотите создать собственную Toolbar в своем макете, например, если вы реализуете шаблон «Навигационный ящик» панели «Надстройка» над дизайном Material Design, вы все равно можете вызвать setSupportActionBar(toolbar) и не пропускать панель инструментов в ActionBarDrawerToggle() позволяя Действие обрабатывает значок навигации.

Но если вы действительно хотите привязать свой ActionBarDrawerToggle к Toolbar которая не является панелью действий в действии, и, возможно, имеет разные стили и другую иконку или что-то еще – есть еще способ.

Дело в том, что, когда вы не передаете панель инструментов в качестве четвертого параметра, предполагается, что активность должна содержать значок навигации (стрелка), а AppCompatActivity возвращает значение атрибута homeAsUpIndicator – оно определено в любом из стандартных приложений AppCompat темы.

Однако, когда вы явно пропускаете Toolbar , ActionBarDrawerToggle ожидает, что экземпляр панели инструментов предоставит индикатор навигации, а он не будет, потому что даже если вы примените к нему соответствующий стиль:

 <android.support.v7.widget.Toolbar ... app:theme="?actionBarTheme" style="@style/Widget.AppCompat.Toolbar"> 

По какой-то причине (возможно, это даже ошибка), стиль Widget.AppCompat.Toolbar не имеет атрибута navigationIcon , поэтому Toolbar возвращает значение null когда ActionBarDrawerToggle запрашивает его для значка nav. Итак, чтобы справиться с этим, вы просто извлекаете из стиля и добавляете атрибут:

 <android.support.v7.widget.Toolbar ... app:theme="?actionBarTheme" style="@style/MyWidget.Toolbar"> <!-- styles.xml --> <style name="MyWidget.Toolbar" parent="Widget.AppCompat.Toolbar"> <item name="navigationIcon">?homeAsUpIndicator</item> </style> 

Теперь вы можете использовать конструктор ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0) с поддержкой панели инструментов ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0) и по-прежнему иметь значок навигации.

Эта строка гарантирует, что значок гамбургера будет изменен на стрелку при нажатии. Убедитесь, что это написано в коде.

 mDrawerLayout.setDrawerListener(mDrawerToggle);