How to replace the hamburger icon used for ActionBarToggle on Android Toolbar with a custom drawable?

。_饼干妹妹 提交于 2019-11-28 04:41:27

You can use the toolbar as Stand Alone mode, that means you should not use your toolbar as part of your ActionBarDrawerToggle constructor, you can achieve that using the below code:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, null,
                       R.drawable.appbar, R.drawable.appbar)

(Note how the toolbar instance is not being sent to the ActionBarDrawerToggle constructor)

Also, you should inflate your menu manually

mToolbar = (Toolbar) findViewById(R.id.nav_toolbar);
mToolbar.inflateMenu(R.menu.base);

And remove the setSupportActionBar(mToolbar); line of code.

Of course, you will have to handle the navigation click by yourself:

mToolbar.setOnMenuItemClickListener(new OnMenuItemClickListener() ...

Then, you can open your drawer like this:

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

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

Hope this may help.

PhoEn-X

These two lines of code work for me:

mDrawerToggle.setDrawerIndicatorEnabled(false); //disable "hamburger to arrow" drawable
mDrawerToggle.setHomeAsUpIndicator(R.drawable.ic_drawer); //set your own

And then call this:

mDrawerToggle.syncState();

My solution is by subclassing 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);
            }
        });
     }
}

The default menu drawable for the ActionBarDrawerToggle is DrawerArrowDrawable.

You can subclass this to add custom functionality, like badges, like so:

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

Usage:

actionBarDrawerToggle.setDrawerArrowDrawable(new BadgedDrawerArrowDrawable(activity));

the thing that worked for me is that i just needed to call toolbar.setNavigationIcon(R.drawable.ic_camera_alt_24dp); at the end of onCreate, or at least after mDrawerToggle = new ActionBarDrawerToggle...

As for v7 support library - you can create your own representation of 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);

as of Jan 2018, this is a working solution (at least for me):

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

things to care:

  • setSupportActionBar should be commented out
  • ActionBarDrawerToggle is not taking a reference to toolbar
  • We should inflate menu ourself, and handle onClicks. onCreateOptionsMenu and onOptionsItemSelected will not be functioning.
  • Don't forget to call toggle.syncState()

Here's how I was able to finally get mine to work.

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

It turned out to be the

mDrawerToggle.syncState();

That finally got everything to work.

I think it is recommended to put the call to syncState() in the onPostCreate(...) lifecycle method.

@Override
public void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this,drawer,toolbar,R.string.navigation_drawer_open,R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);

toggle.syncState();
toolbar.setNavigationIcon(R.drawable.ic_action_name);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!