如何将Android工具栏上用于ActionBarToggle的汉堡包图标替换为自定义可绘制图标?

如何将Android工具栏上用于ActionBarToggle的汉堡包图标替换为自定义可绘制图标?,android,navigation-drawer,android-toolbar,Android,Navigation Drawer,Android Toolbar,我使用Android 5.0中的新工具栏实现了一个基本的ActionBarDrawerToggle 但是,我不知道如何更改提供的默认汉堡图标。 从android文档中可以看出,“给定的活动将链接到指定的抽屉布局,工具栏的导航图标将设置为自定义的可绘制图标……当抽屉关闭时,此可绘制图标显示一个汉堡图标,当抽屉打开时显示一个箭头。当抽屉打开时,它会在这两种状态之间设置动画。” 我目前有这一切工作正常与以下代码,但我想取代默认提供的汉堡包与我自己的绘图 这是我目前的代码: MainActivity.j

我使用Android 5.0中的新工具栏实现了一个基本的ActionBarDrawerToggle

但是,我不知道如何更改提供的默认汉堡图标。 从android文档中可以看出,“给定的活动将链接到指定的抽屉布局,工具栏的导航图标将设置为自定义的可绘制图标……当抽屉关闭时,此可绘制图标显示一个汉堡图标,当抽屉打开时显示一个箭头。当抽屉打开时,它会在这两种状态之间设置动画。”

我目前有这一切工作正常与以下代码,但我想取代默认提供的汉堡包与我自己的绘图

这是我目前的代码:

MainActivity.java

@InjectView(R.id.main_activity_toolbar)
Toolbar mToolbar;

@InjectView(R.id.main_activity_drawer_layout)
DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.main_activity);
    super.onCreate(savedInstanceState);

    setSupportActionBar(mToolbar);
    mToolbar.setNavigationIcon(R.drawable.navigation);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open, R.string.drawer_close) {
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            invalidateOptionsMenu();
        }

        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            invalidateOptionsMenu();
        }
    };

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);
}
这一行:

mToolbar.setNavigationIcon(R.drawable.navigation);
似乎不起作用

这可能吗?谢谢


ActionBarToggle文档-

您可以将工具栏作为独立模式使用,这意味着您不应该将工具栏作为ActionBarDrawerToggle构造函数的一部分使用,您可以使用以下代码实现这一点:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, null,
                       R.drawable.appbar, R.drawable.appbar)
(注意工具栏实例如何未发送到ActionBarDrawerToggle构造函数)

此外,您应该手动为菜单充气

mToolbar = (Toolbar) findViewById(R.id.nav_toolbar);
mToolbar.inflateMenu(R.menu.base);
移除设置支持操作栏(mToolbar);代码行

当然,您必须自己处理导航单击:

mToolbar.setOnMenuItemClickListener(new OnMenuItemClickListener() ...
然后,你可以像这样打开你的抽屉:

drawerButton = (BadgeDrawerButton) findViewById(R.id.badge_drawer_button);
drawerButton.setOnClickListener(
                       new View.OnClickListener() {

                              @Override
                              public void onClick(View v) {
                                     mDrawerLayout.openDrawer(Gravity.LEFT);
                              }
                       });

希望这能有所帮助。

以下是我如何最终让自己的工作投入到工作中的

private Toolbar toolbar;
toolbar = (Toolbar) findViewById(R.id.toolbar);

if (toolbar != null) {
    setSupportActionBar(toolbar);
    toolbar.setNavigationIcon(R.drawable.ic_drawer);

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

        /** Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
        }
    };

    // Set the drawer toggle as the DrawerListener
    mDrawerLayout.setDrawerListener(mDrawerToggle);
    mDrawerToggle.syncState();

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);
}
结果证明是

mDrawerToggle.syncState();

这终于让一切都开始工作了。

我的解决方案是将ActionBarDrawerToggle子类化

public class MyActionBarDrawerToggle extends android.support.v7.app.ActionBarDrawerToggle {

    public MyActionBarDrawerToggle(Activity activity, final DrawerLayout drawerLayout, Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
        super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);

        setHomeAsUpIndicator(R.drawable.drawer_toggle);
        setDrawerIndicatorEnabled(false);

        setToolbarNavigationClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                drawerLayout.openDrawer(Gravity.LEFT);
            }
        });
     }
}

这两行代码适用于我:

mDrawerToggle.setDrawerIndicatorEnabled(false); //disable "hamburger to arrow" drawable
mDrawerToggle.setHomeAsUpIndicator(R.drawable.ic_drawer); //set your own
然后称之为:

mDrawerToggle.syncState();

对我有效的是,我只需要调用
toolbar.setNavigationIcon(R.drawable.ic\u camera\u alt\u 24dp)

在onCreate结束时,或者至少在
mDrawerToggle=newactionbardrawertoggle…
之后,我认为建议在
onPostCreate(…)
生命周期方法中调用
syncState()

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

ActionBarDrawerToggle的默认可绘制菜单为DrawerRowDrawable

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {

            public void onDrawerClosed(View view) {
                supportInvalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                supportInvalidateOptionsMenu();
            }
        };
        mDrawerToggle.setDrawerIndicatorEnabled(true);

        DrawerArrowDrawable drawerArrowDrawable = new DrawerArrowDrawable(this);
        drawerArrowDrawable.setAlpha(1);
        drawerArrowDrawable.setSpinEnabled(false);
        drawerArrowDrawable.setDirection(DrawerArrowDrawable.ARROW_DIRECTION_LEFT);
        drawerArrowDrawable.setColor(Color.BLACK);

        mDrawerToggle.setDrawerArrowDrawable(drawerArrowDrawable);
您可以将其子类化以添加自定义功能,如徽章,如下所示:

public class BadgedDrawerArrowDrawable extends DrawerArrowDrawable {

    /**
     * @param context used to get the configuration for the drawable from
     */
    public BadgedDrawerArrowDrawable(Context context) {
        super(context);

        setColor(context.getResources().getColor(R.color.colorAccent));
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);
        paint.setTextSize(60);
        canvas.drawText("!", canvas.getWidth() - 60, 25, paint);
    }
}
用法:

actionBarDrawerToggle.setDrawerArrowDrawable(new BadgedDrawerArrowDrawable(activity));

至于v7支持库,您可以创建自己的DrawerArrowDrawable表示

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {

            public void onDrawerClosed(View view) {
                supportInvalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                supportInvalidateOptionsMenu();
            }
        };
        mDrawerToggle.setDrawerIndicatorEnabled(true);

        DrawerArrowDrawable drawerArrowDrawable = new DrawerArrowDrawable(this);
        drawerArrowDrawable.setAlpha(1);
        drawerArrowDrawable.setSpinEnabled(false);
        drawerArrowDrawable.setDirection(DrawerArrowDrawable.ARROW_DIRECTION_LEFT);
        drawerArrowDrawable.setColor(Color.BLACK);

        mDrawerToggle.setDrawerArrowDrawable(drawerArrowDrawable);

截至2018年1月,这是一个有效的解决方案(至少对我而言):

注意事项:

  • setSupportActionBar
    应注释掉
  • ActionBarDrawerToggle
    未引用
    工具栏
  • 我们应该自己给菜单充气,然后处理一次
    oncreateoptions菜单
    和选择的选项项
将不起作用
  • 不要忘记调用
    toggle.syncState()

  • 谢谢你的建议!这确实有效,但是如何让图标转到菜单栏的左侧呢?此外,如果您使用mToolbar.setNavigationIcon(resId),则必须跟踪抽屉是否打开,以知道您应该调用openDrawer还是closeDrawer,对吗;它会为你放置它。是的,您需要跟踪抽屉状态(打开、关闭),但为了简洁起见,我省略了这些行。如果这对您有帮助,请标记答案。
    if(mDrawerLayout.isDrawerOpen()){mDrawerLayout.closeDrawer(mDrawer);}否则{mDrawerLayout.openDrawer(mDrawer);}
    不清楚需要做什么。我需要在菜单中添加抽屉图标吗?我试过了,现在工具栏上有两个自定义图标,但没有一个可以处理点击事件。我猜这是因为我没有实现抽屉按钮的onClick,但我不知道如何处理它(找不到对BadgeDroperButton的引用)以及按钮的定义位置。我相信这个答案是针对v4支持库的,不会与v7库一起使用。有它自己的问题。当您在fragmentManager上弹出Backstack时,stock hamburger图标会返回。您的代码更改图标,但图标的单击已消失。我们可以按照以下步骤解决此问题,但此问题不起作用。与上述答案相同的问题-一旦按下向上箭头关闭抽屉,库存汉堡图标将临时显示,然后替换为自定义图标。我正在寻找一个完全消除它的解决方案。太棒了。为汉堡包添加标签的完美解决方案。我唯一要指出的是,在draw()调用中没有分配Paint。我创建了一个简化版的
    ActionBarDrawerToggle
    ,它使用了参考资料中的
    drawable
        //setSupportActionBar(toolbar)
    
        val toggle = ActionBarDrawerToggle(this, drawer_layout, null, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        toolbar.inflateMenu(R.menu.menu_main)
        toolbar.setNavigationIcon(R.drawable.ic_menu)
        toolbar.setNavigationOnClickListener {
            drawer_layout.openDrawer(Gravity.START)
        }
    
        toolbar.setOnMenuItemClickListener {
            true
        }
    
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()
    
        nav_view.setNavigationItemSelectedListener(this)