Как заменить значок гамбургера, используемый для ActionBarToggle на панели инструментов Android, на собственный рисунок?

Я реализовал базовый ActionBarDrawerToggle, используя новую панель инструментов в Android 5.0.

Тем не менее, я не могу понять, как изменить значок гамбургера по умолчанию, который поставляется. В документации по Android говорится, что "данное действие будет связано с указанным DrawerLayout, а значок навигации на панели инструментов будет установлен на собственный чертеж... Этот чертеж показывает значок гамбургера, когда ящик закрыт, и стрелку, когда ящик открыт. Это оживляет между этими двумя состояниями, как ящик открывается ".

В настоящее время у меня все это работает правильно со следующим кодом, однако я хочу заменить поставляемый по умолчанию гамбургер на свой собственный drawable.

Вот мой текущий код:

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 - https://developer.android.com/reference/android/support/v7/app/ActionBarDrawerToggle.html

10 ответов

Решение

Вы можете использовать панель инструментов как автономный режим, это означает, что вы не должны использовать свою панель инструментов как часть вашего конструктора 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);

И удалите setSupportActionBar(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);
                              }
                       });

Надеюсь, что это может помочь.

Эти две строки кода работают для меня:

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

А потом назовите это:

mDrawerToggle.syncState();

Меню по умолчанию, которое можно нарисовать для ActionBarDrawerToggle - 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));

У меня сработало то, что мне просто нужно было позвонить toolbar.setNavigationIcon(R.drawable.ic_camera_alt_24dp); в конце onCreate или, по крайней мере, после mDrawerToggle = new ActionBarDrawerToggle...

Мое решение заключается в создании подкласса 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);
            }
        });
     }
}
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);

По состоянию на январь 2018 года это рабочее решение (по крайней мере, для меня):

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

вещи по уходу:

  • setSupportActionBar следует закомментировать
  • ActionBarDrawerToggle не брать ссылку на toolbar
  • Мы должны сами надувать меню и обрабатывать клики. onCreateOptionsMenu а также onOptionsItemSelected не будет функционировать.
  • Не забудьте позвонить toggle.syncState()

Что касается библиотеки поддержки 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);

Вот как я смог наконец заставить мою работу.

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

Вот наконец-то все заработало.

Я думаю, что рекомендуется позвонить syncState() в onPostCreate(...) метод жизненного цикла.

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

Я создал упрощенную версию ActionBarDrawerToggle который использует drawable из ресурсов: класс StaticActionBarDrawerToggle

Другие вопросы по тегам