NavigationDrawer в стиле Material

c8tn8OCNDYA

Здравствуйте. В этом уроке я расскажу о библиотеке MaterialDrawer. Библиотека реализует функционал NavigationDrawer в стиле MaterialDesign.

Поддерживается Android начиная с IceCreamSanwich (API 14). Из особенностей можно выделить то, что боковое меню может вылезать как справа, так и слева. Также можно настроить расположение панели меню над или под Toolbar’ом. Как обычно, исходники выложены на GitHub, ссылки на них приведены в конце статьи.

Для работы библиотеки нам нужно подключить AndroidSupportLibrary v7 к проекту.

Подготовка

После создания проекта  нам нужно добавить Toolbar в каждое Activity. Как это сделать описано в этой статье.

Найдем Toolbar и установим его в качестве ActionBar’а:

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
		setSupportActionBar(toolbar);

	}

}

Теперь, мы можем подключить NavigationDrawer:

Drawer result = new DrawerBuilder()
.withActivity(this)
.build();

После этого у нас есть пустой NavigationDrawer.

nxr4Z6HT_80

Настраиваем меню

Прежде чем мы начнем добавлять элементы в боковое меню нам надо его настроить.

Чтобы Drawer вылазил под Toolbar’ом нам нужно вызвать метод withDisplayBelowToolbar(boolean):

Drawer result= new DrawerBuilder()
	.withActivity(this)
	.withToolbar(toolbar)
	.withDisplayBelowToolbar(true)
	.build();

Включаем подсветку статусбара:

.withTranslucentStatusBar(true)

Показываем кнопку назад:

result.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false); 
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

Включаем анимацию стрелки:

.withActionBarDrawerToggleAnimated(true)

Открываем Drawer:

result.openDrawer();

Закрываем Drawer:

result.closeDrawer();

Проверяем, открыт Drawer или нет:

result.isDrawerOpen();

Убираем затемнение при открытие меню:

result.getDrawerLayout().setScrimColor(Color.TRANSPARENT);

Отображение под Toolbar’ом:

.withDisplayBelowToolbar(true)

 

Изменяем фона слайдера

Также мы можем поменять фон у бокового меню. В качестве фона можно установить цвет или Drawable.

Меняем цвет фона:

.withSliderBackgroundColor(Color.DKGRAY)

Берем цвет  фона из ресурсов:

.withSliderBackgroundColorRes(R.color.drawer_bg)

Устанавливаем Drawable в качестве фона:

.withSliderBackgroundDrawable(getResources().getDrawable(R.drawable.drawer_bg))

Берем Drawable из ресурсов.

.withSliderBackgroundDrawableRes(R.drawable.drawer_bg)
Добавляем пункты меню

Элементы в Drawer добавляются через метод  addDrawerItems(IDrawerItem… drawerItems):

DrawerBuilder()
    .withActivity(this)
    .addDrawerItems(
        new PrimaryDrawerItem()
        .withName(R.string.drawer_item_home)
        .withIdentifier(1)
    )
    .build();

Все элементы в MaterialDrawer делятся на 5 типов:

1) BaseDrawerItem
2) DividerDrawerItem
3) PrimaryDrawerItem
4) SecondaryDrawerItem
5) SectionDrawerItem

Мы рассмотрим каждый из них.

BaseDrawerItem

Базовый класс для всех элементов. Не имеет конструктора, поэтому мы не можем добавлять его в меню. Едем дальше.

DividerDrawerItem

Это обычная разделительная линия. Пример:

new DividerDrawerItem()

PrimaryDrawerItem

Пункт меню. Пример:

new PrimaryDrawerItem().withName(R.string.drawer_item_name)

В методе withName мы можем передать как id строки (тогда библиотеки автоматически возьмет строку из ресурсов) или же сразу передать строку.

Меняем цвет выделенного пункта:

.withSelectedColor(R.id.my_selected_icon)

Берем цвет выделенного пункта из ресурсов:

.withSelectedColorRes(R.color.selected_drawer_item)

Меняем цвет текста выделенного пункта:

.withSelectedTextColor(Color.BLUE)

Берем цвет текста выделенного пункта из ресурсов:

.withSelectedTextColorRes(R.color.selected_drawer_item)

Добавляем иконку:

.withIcon(getResources().getDrawable(R.id.my_icon)

Меняем иконку выделенного пункта:

.withSelectedIcon(R.id.my_selected_icon)

Добавляем бейдж:

.withBadge("100")

Добавляем описание:

.withDescription(R.string.drawer_item_description)

Меняем цвет текста:

.withTextColor(Color.RED)

Меняем цвет текста  выделенного пункта:

.withSelectedTextColorRes(Color.BLACK)

Изменяем шрифт текста:

.withTypeface(yourTypeface)

SectionDrawerItem

Разделительная линия с надписью. Пример:

 new SectionDrawerItem().withName(R.string.drawer_item_name)

Меняем цвет текста:

.withTextColor(Color.RED)

Изменяем шрифт текста:

.withTypeface(yourTypeface)
Добавляем блок с профилями

5jIIHBxNyCI

Добавление блока с профилями в NavigationDrawer осуществляется с помощью класса AccountHeader. Работает он по тому же принципу что и класс Drawer.Простой пример:

AccountHeader.Result headerResult = new AccountHeader()
 .withActivity(this)
 .withHeaderBackground(R.drawable.header)
 .build();

Drawer result = new DrawerBuilder()
 .withActivity(this)
 .withToolbar(toolbar)
 .withAccountHeader(headerResult)
 .build();

Вот что у нас получилось:

EWFYwlpO2Z0

Тут тоже есть два типа элементов:

1) ProfileDrawerItem

2) ProfileSettingDrawerItem

ProfileDrawerItem — это, собственно, сам профиль.

ProfileDrawerItem

ProfileSettingDrawerItem — пункты меню для управления профилями.

ProfileSettingDrawerItem

Чтобы добавить  профили в наш блок нужно вызвать метод addProfiles(IProfile… profiles) и передать ему объекты класса ProfileDrawerItem или ProfileSettingDrawerItem. Простой пример:

IProfile profile = new ProfileDrawerItem()
 .withName("Java-Help")
 .withEmail("java-help@mail.ru")
 .withIcon(getResources().getDrawable(R.drawable.profile));

AccountHeader.Result headerResult = new AccountHeader()
 .withActivity(this)
 .withHeaderBackground(R.drawable.header)
 .addProfiles(profile);
 .build();

Теперь рассмотрим методы классов ProfileDrawerItem  и ProfileSettingDrawerItem. Ниже я буду приводить имя метода с параметрами и его описание.

ProfileDrawerItem  

withName(String name) — устанавливаем имя профилю
withEmail(String email) — устанавливаем E-mail профилю
withIcon(Drawable icon) — устанавливаем иконку профилю

ProfileSettingDrawerItem

withName(String name) — устанавливаем имя пункту
withIcon(Drawable icon) — устанавливаем иконку пункту
withIdentifier(int identifier) — устанавливаем ID пункту
withTextColor(int textColor) — устанавливаем цвет текста пункту
withTextColorRes(int textColorRes) — устанавливаем цвет текста пункту из ресурсов
withTypeface(Typeface typeface) — устанавливаем шрифт текста пункту

Делаем блок  профилями компактным:

.withCompactStyle(true)
Обрабатываем нажатия

Для того, чтобы обработать нажатие на пункт меню нм нужно вызвать метод withOnDrawerItemClickListener и  передать реализацию интерфейса OnDrawerItemClickListener:

.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
   @Override
   public boolean onItemClick(AdapterView<?> parent, View view, int position, long id, IDrawerItem drawerItem) {
       switch(drawerItem.getIdentifier()){
          case 0:

          break;
       }
       return true;
    }
})

 

Добавляем еще один Drawer
Drawer result = new DrawerBuilder()
    .withActivity(this)
    .withToolbar(toolbar)
    .addDrawerItems(
        //добавляем пункты
    )
    .build();

new Drawer()
    .withActivity(this)
    .addDrawerItems(
        //добавляем пункты
    )
    .withDrawerGravity(Gravity.END)
    .append(result);
 Закрываем меню при нажатии кнопки назад
@Override
public void onBackPressed() {
    if (result != null && result.isDrawerOpen()) {
        result.closeDrawer();
    } else {
       super.onBackPressed();
    }
}

Библиотека на GitHub: MaterialDrawer.
Исходники примера: MaterialDrawer.

Комментарии:

16 comments

  1. Дмитрий Reply

    Спасибо Вам большое за пример. Дня бы 3 -4 назад нашел бы его, с экономил бы кучу времени.

    Будьте добры подскажите в чем может быть проблема=(
    У меня не отображается в toolbar название выбранного пункта меню. Просто пустое поле и все(

  2. Nappa Reply

    Thank you for this article, it’ great. How can I implements the mini-drawer bar?

  3. Дмитрий Reply

    подскажите, а как реализовать переход по пунктам из navigation drawer например на другое окно. к примеру по при нажатии «о программе» переходило бы на окно «о программе»

    • lemhell Reply

      Вам необходимо создать Intent и передать его в метод startActivity(), вызывая этот метод в onClickListener необходимого пункта меню.

  4. Andrei Reply

    Подскажите почему метод .withDisplayBelowToolbar(true) у меня не работает
    Error:(39, 17) error: cannot find symbol method withDisplayBelowToolbar(boolean)-
    эту ошибку выдает в логах ?

  5. Andrei Reply

    Ваш пример устарел, библиотека обновилась и те методы которые тут описаны либо не работают вообще, либо работают но с другим синтаксисом.

    • Admin Post authorReply

      Какие именно? Исправим

  6. Alexander Crone Reply

    AccountHeader.Result headerResult вот это точно устарело)

    А чем спрашивать, лучше на гите сравните сами)

  7. QM Reply

    А как сделать кнопку назад в тулбаре, при клике которого не открывался этот меню, а возвращался в предыдущий фрагмент?

  8. Rus Reply

    А как временно отключить меню? Не нашел ни одного подходящего метода…

  9. zTrap Reply

    Разделительную полосу, того же плана, в drawer из шаблона as возможно сделать?

  10. Artem Reply

    метод .withDisplayBelowToolbar(true) устарел, скажите как все же засунуть его под тулбар ?
    Пожалуйста.

  11. Бекназар Reply

    Добрый день.
    А можно это реализовать в Basic4android?

    • Admin Post authorReply

      Здравствуйте, я мало знаю о Basic4Android (практически ничего), поэтому не смогу ответить на ваш вопрос.

  12. Mayur Reply

    Hello,
    Thank you for this great tutorial. How can I add the hamburger icon to an activity?
    If I am opening a fragment from this drawer item then it shows a hamburger icon in the toolbar and if I am opening an activity, then it is showing me a back button.

    Please let me know how I can change the toolbar icon to show hamburger icon for an activity.

    Thanks,
    Mayur

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *