【问题标题】:Toolbar Navigation Hamburger Icon missing工具栏导航汉堡图标丢失
【发布时间】:2015-03-20 05:46:39
【问题描述】:

我正在寻找一种使用 Drawer/DrawerToggle 显示汉堡包图标的方法,并使用 Android 中包含的默认图标

通过设置getSupportActionBar().setDisplayHomeAsUpEnabled(true); 它显示后退箭头但不显示汉堡包。 Stackoverflow 上的其他帖子(如 thisthis)使用 DrawerLayout 或自定义可绘制对象。我在 Android 源代码中找不到汉堡包图标的矢量或 png。

你知道如何在 android/support 库中找到原始的汉堡包图标吗?(或如何显示它)

注意:矢量和 png 可以在 google.com/design 网站上找到: http://www.google.com/design/spec/resources/sticker-sheets-icons.html#

在我的活动中

mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(LOG_TAG, "navigation clicked");
    }
});

布局文件

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

样式.xml

<!-- Base application theme. -->
<style name="Theme.AppTheme" parent="Theme.AppCompat.Light.NoActionBar">


    <item name="colorPrimary">@color/primaryDef</item>
    <item name="colorPrimaryDark">@color/primaryDarkDef</item>
    <item name="colorAccent">@color/primaryDef</item>

    <!-- Remove the actionbar shadow-->
    <item name="android:windowContentOverlay">@null</item>
</style>

【问题讨论】:

  • @PedroOliveira 这不是重复的,因为我明确地说我没有使用 ActionBarDrawerToggle
  • 那么,如果您不使用抽屉,您应该如何显示菜单?那个汉堡包图标是抽屉的一部分。
  • @PedroOliveira 这不是主要问题,但它不用于显示手册。我知道这违反了用户体验指南,并且不会出现在公共应用程序中。如果可能的话,问题只是在 Android 中找到图标。
  • @ASP 这个不回答问题

标签: android android-support-library material-design android-toolbar


【解决方案1】:

如果您想使用与棒棒糖相同的抽屉,那么让我告诉您这不是静态图像。该图像由名为DrawerArrowDrawableToggle 的类实时绘制。所以没有“汉堡包”图标。

但是,如果您想要没有动画的汉堡图标,您可以在这里找到它:

https://material.io/tools/icons/?icon=menu&style=baseline

【讨论】:

  • 您的回答完成了问题的 50%,谢谢!你知道在棒棒糖前设备上实现这个的方法吗?
  • 如果你想用汉堡菜单实现漂亮的动画,我建议你查找 appcompatv7 并设置一个抽屉菜单。如果您只想显示菜单图标,那么只需将图像放在可绘制对象中并使用它。我将在此处发布我的 repo,其中包含适用于棒棒糖前设备的“Material Drawer”上一个漂亮而简单的模板:) github.com/kanytu/android-material-drawer-template
  • 谢谢您,您能否完成您的回答以包括google.com/design/spec/resources/…,我们还可以在其中找到官方图标。不是那个矢量图标需要 API 21,所以我们必须使用 png
  • 该网站上的朋友,您只需单击“下载 ZIP”,它就会下载所有具有相同可绘制文件夹结构的 android 项目使用的 png :) 去那里。选择您喜欢的颜色,点击下载 zip,然后将“res”文件夹拖到您自己的“res”文件夹中:)
  • 已编辑。这能完成工作吗? :)
【解决方案2】:

要获得动画汉堡包图标,您应该使用DrawerLayoutActionBarDrawerToggle,并为ActionBarActionBarDrawerToggle 启用图标。

例子:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle mDrawerToggle;

setSupportActionBar(toolbar);
final ActionBar actionBar = getSupportActionBar();

if (actionBar != null)
{
   actionBar.setDisplayHomeAsUpEnabled(true);
   mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.hello_world, R.string.hello_world)
   {

      public void onDrawerClosed(View view)
      {
         supportInvalidateOptionsMenu();
         //drawerOpened = false;
      }

      public void onDrawerOpened(View drawerView)
      {
         supportInvalidateOptionsMenu();
         //drawerOpened = true;
      }
   };
   mDrawerToggle.setDrawerIndicatorEnabled(true);
   drawerLayout.setDrawerListener(mDrawerToggle);
   mDrawerToggle.syncState();
}

另外,您需要将这些方法添加到您的活动中:

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

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

【讨论】:

  • 确实不起作用...直到我意识到缺少的drawerLayout.syncState 使汉堡图标出现:)
  • @ptitvinou,请参阅更新的答案。我添加缺少的方法。
  • @mohax 我怎样才能只显示汉堡包图标而不是后退箭头?
  • @SibeliusSeraphini,这条线可以做到mDrawerToggle.setDrawerIndicatorEnabled(true);。如果您将false 作为参数传递,您将看到后退箭头。不要忘记从答案末尾添加2个方法到活动类'
  • @mohax 我需要添加这一行:mDrawerToggle.syncState();在drawerLayout.setDrawerListener(mDrawerToggle);之后
【解决方案3】:

为此,您只需要写几行

   DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
   ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
   drawer.addDrawerListener(toggle);
   toggle.setDrawerIndicatorEnabled(true);
   toggle.syncState();

toggle.setDrawerIndicatorEnabled(true); 如果为假,则使其为真或删除此行

【讨论】:

  • 我无法理解一件事。如果那个汉堡图标的主要功能是打开抽屉,那我们为什么要单独给它添加drawlistener呢?
【解决方案4】:

这是对我有用的最简单的解决方案。

ActionBarDrawerToggle 有两种类型的构造函数。其中之一以 toolbar 作为参数。使用它(下面的第二个)来获得动画汉堡包。

ActionBarDrawerToggle(this, mDrawerLayout, R.string.content_desc_drawer_open, 
R.string.content_desc_drawer_close);

ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.content_desc_drawer_open, 
R.string.content_desc_drawer_close);`  //use this constructor

【讨论】:

    【解决方案5】:

    您可以尝试为这样的汉堡图标制作自己的可绘制对象。

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0">
        <path
            android:fillColor="#ffffff"
            android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z" />
    </vector>
    

    然后在你的片段/活动中,

    getSupportActionBar().setHomeAsUpIndicator(R.drawable.as_above);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    

    对于其他可绘制对象,这可能会有所帮助:https://github.com/google/material-design-icons/blob/master/navigation/drawable-anydpi-v21/

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,我在这里找到了最简单的解决方案:

      appcompatv7-v21-navigation-drawer-not-showing-hamburger-icon

      我所要做的就是打电话:

      mDrawerToggle.syncState();
      

      【讨论】:

        【解决方案7】:

        我遇到了同样的问题。 获取ToolBar,然后设置导航图标

        final android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationIcon(R.drawable.blablabla);
        

        【讨论】:

          【解决方案8】:
              Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
              mToolbar.setTitle("title");
              setSupportActionBar(mToolbar);
              getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
              getSupportActionBar().setHomeButtonEnabled(true);
              getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_list);
          

          【讨论】:

            【解决方案9】:

            可以隐藏后退箭头使用

            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
            getSupportActionBar().setHomeButtonEnabled(false);
            

            然后在网页中找到汉堡图标->hamburger

            最后,使用操作栏方法在您的项目中设置此可绘制对象:

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

            【讨论】:

            • 我在 support lib 或 android sdk 中搜索汉堡包图标。
            • @AlexPerl 也许你做错了什么。你能告诉我你的情况吗?
            【解决方案10】:
             ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
                        R.string.navigation_drawer_open, R.string.navigation_drawer_close);
                drawer.addDrawerListener(toggle);
                toggle.syncState();
            

            这是我的工作

            【讨论】:

              【解决方案11】:

              也许你可以试试这个,但你会失去箭头和汉堡图标之间的动画

              @Override
              protected void onCreate(Bundle arg0) {
                  super.onCreate(arg0);
                  super.setContentView(R.layout.activity_menu_drawer_left);
              
              _drawerToggle = new ActionBarDrawerToggle(this, _drawerLayout, R.string.drawer_opened, R.string.drawer_closed) {
                      public void onDrawerOpened(View drawerView) {
                          super.onDrawerOpened(drawerView);
                          changeDrawerIconOnDrawerClick(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
                      }
              
                      /** Called when a drawer has settled in a completely closed state. */
                      public void onDrawerClosed(View view) {
                          super.onDrawerClosed(view);
                          changeDrawerIconOnDrawerClick(R.drawable.ic_drawer);
                      }
                  };
              
                   //to change default icon to hamburger item initially
                  changeDrawerIconOnDrawerClick(R.drawable.ic_drawer);    }
              
              
              
              private void changeDrawerIconOnDrawerClick(int resourceId) {
                  //Drawable icon = ContextCompat.getDrawable(getApplicationContext(), resourceId);
                  Drawable icon = ResourcesCompat.getDrawable(getResources(), resourceId, null);
                  icon.setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
                  _drawerToggle.setDrawerIndicatorEnabled(false);
                  _drawerToggle.setHomeAsUpIndicator(icon);
              }
              

              【讨论】:

                【解决方案12】:

                用你自己的drawable替换默认的向上箭头

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

                【讨论】:

                  【解决方案13】:

                  只需在您的 onCreate 方法中添加以下内容,

                  if (getSupportActionBar() != null) {
                              getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                              getSupportActionBar().setHomeButtonEnabled(true);
                          }
                  
                          ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                                  this, mDrawer, mToolbar, R.string.home_navigation_drawer_open, R.string.home_navigation_drawer_close) {
                  
                              public void onDrawerClosed(View view) {
                                  super.onDrawerClosed(view);
                                  invalidateOptionsMenu();
                              }
                  
                              public void onDrawerOpened(View drawerView) {
                                  super.onDrawerOpened(drawerView);
                                  invalidateOptionsMenu();
                              }
                  
                              @Override
                              public void onDrawerSlide(View drawerView, float slideOffset) {
                                  super.onDrawerSlide(drawerView, slideOffset);
                              }
                          };
                          mDrawer.addDrawerListener(toggle);
                          toggle.syncState();
                  

                  在strings.xml中,

                  <string name="home_navigation_drawer_open">Open navigation drawer</string>
                  <string name="home_navigation_drawer_close">Close navigation drawer</string>
                  

                  【讨论】:

                    【解决方案14】:

                    在 MyActionBarDrawerToggle 中使用这个构造函数:

                        public MyActionBarDrawerToggle(AppCompatActivity host, DrawerLayout drawerlayout, SupportToolbar toolbar, int openedResource, int closedResource)
                            : base(host, drawerlayout, toolbar, openedResource, closedResource)
                        {
                            mHostActivity = host;
                            mOpenedResource = openedResource;
                            mClosedResource = closedResource;
                        }
                    

                    并在 mainActivity 中调用此方法(使用 AppCompatActivity)

                            mDrawerToggle = new MyActionBarDrawerToggle(
                                this,                           //Host Activity
                                mDrawerLayout,                  //DrawerLayout
                                mToolbar,                       //Toolbar
                                Resource.String.openDrawer,     //Opened Message
                                Resource.String.closeDrawer     //Closed Message
                            );
                    
                    
                            mDrawerLayout.AddDrawerListener(mDrawerToggle);
                            SupportActionBar.SetHomeButtonEnabled(true);
                            SupportActionBar.SetDisplayShowTitleEnabled(true);
                            mDrawerToggle.DrawerIndicatorEnabled = true;
                            mDrawerToggle.SyncState();
                    

                    【讨论】:

                      【解决方案15】:

                      onCreate():

                          setSupportActionBar(toolbar);
                          ActionBar actionBar = getSupportActionBar();
                          drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open, R.string.close) {
                              @Override
                              public void onDrawerClosed(View drawerView) {
                                  super.onDrawerClosed(drawerView);
                                  supportInvalidateOptionsMenu();
                              }
                      
                              @Override
                              public void onDrawerOpened(View drawerView) {
                                  super.onDrawerOpened(drawerView);
                                  supportInvalidateOptionsMenu();
                              }
                          };
                          drawerLayout.setDrawerListener(drawerToggle);
                      
                      
                          drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  Backstack.get(MainActivity.this).goBack();
                              }
                          });
                          //actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
                          //getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                          actionBar.setDisplayHomeAsUpEnabled(false);
                          actionBar.setHomeButtonEnabled(true);
                      

                      在设置 UP 导航时:

                      private void setupViewsForKey(Key key) {
                          if(key.shouldShowUp()) {
                              drawerToggle.setDrawerIndicatorEnabled(false);
                              getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                          }
                          else {
                              getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                              drawerToggle.setDrawerIndicatorEnabled(true);
                          }
                          drawerToggle.syncState();
                      

                      【讨论】:

                      【解决方案16】:

                      在 JetPack 中它对我有用

                      NavigationUI.setupWithNavController(vb.toolbar, nav)
                      vb.toolbar.navigationIcon = ResourcesCompat.getDrawable(resources, R.drawable.icon_home, null)
                      

                      【讨论】:

                      • 在您的情况下,vb 是什么?你能提供整个方法/类吗?
                      • vb 这是我的视图绑定