[Из песочницы] Material Design. Динамический Toolbar на живом примере
Уверен, что те, кто следят за изменениями в мире Android, заметили, что Toolbar начинает играть в приложениях всё более значимую роль. Например в последней версии Gmail клиента в Toolbar вынесен почти весь функционал по работе с почтой, а в новом Google Chrome Toolbar отвечает за работу с текстом страниц.В данной статье я постараюсь рассказать о создании динамического Toolbar, который позволит пользователю работать с контентом четырьмя различными способами в рамках одного Activity. Мы рассмотрим весь процесс разработки Toolbar-a начиная с xml файлов стилей и заканчивая анимацией иконок, а в конце статьи я оставлю ссылку на GitHub репозиторий с примером полностью рабочего приложения.
Начнём с постановки задачиМы будем разрабатывать Toolbar для приложения, которое позволит пользователю следить за изменениями цен на акции. На главном экране будет расположен список всех акций, за которыми следит пользователь, мы также должны реализовать базовый функционал: удаление, поиск и сортировку акций. Вот так я реализовал этот функционал с помощью динамического Toolbar-a: Стандартный режим Режим поиска Режим удаления Режим сортировки Создаём xml файлы конфигураций Итак, в первую очередь нам нужно создать xml файл самого Toolbar-a. Я советую сделать это в отдельном файле, так как в будущем мы скорее всего захотим использовать один и тот же (или похожий) Toolbar во всех Activity нашего приложения.res/layout/toolbar.xml
Создавать элементы внутри меню (Menu), как экземпляры класса MenuItem. Этот способ использовался в предыдущих версиях Анрдроид (API Level < 21), когда еще не было Toolbar. Создавать все элементы, как обычные View внутри файла toolbar.xml. Я решил использовать способ с меню потому, что во-первых, так нам не нужно создавать свой лейаут для Toolbar-а. Во-вторых, у нас не будет проблем с обратной совместимостью и в-третьих, мы избежим конфликтов между Toolbar и Navigation Drawer (боковое меню присутствующие в приложении и управляющиеся с помощью ActionBarDrawerToggle, который в свою очередь работает с MenuItem)res/menu/menu_activity_main.xml
Добавляем Toolbar к Activity Все xml файлы созданы и теперь мы можем добавить Toolbar к Activity. Для начала перезапишем метод onCreateOptionsMenu, который отвечает за инициализацию меню. @Override public boolean onCreateOptionsMenu (Menu menu) { getMenuInflater ().inflate (R.menu.menu_activity_main, menu); return true; } Теперь зададим Toolbar, как ActioanBar, это обеспечит нам обратную совместимость с предыдущими версиями Android (API Level @Override protected void onCreate (Bundle savedInstanceState) { Toolbar mActionBarToolbar = (Toolbar) findViewById (R.id.toolbar_actionbar); setSupportActionBar (mActionBarToolbar); } Управление элементами Toolbar Полный код отвечающий за управление элементами вы можете посмотреть в репозитории примера на github, а в статье мы остановимся на основных методах: Метод onOptionsItemSelected (MenuItem item) — вызывается при любом нажатии по элементу внутри Toolbar Метод onMenuItemActionExpand (MenuItem item) — вызывается, когда виджет поиска переходит в активное состояние. Для того, чтобы этот метод вызвался необходимо реализовать интерфейс MenuItemCompat.OnActionExpandListener, и затем задать его для MenuItem поиска: MenuItemCompat.setOnActionExpandListener (searchMenuItem, this); //this — интерфейс MenuItemCompat.OnActionExpandListener Метод onMenuItemActionCollapse — вызывается при закрытии виджета поиска, для него также необходимо реализовать интерфейс OnActionExpandListener. Вы также можете вызвать его искусственно, например когда пользователь нажимает кнопку «назад». Пример: @Override public void onBackPressed () { if (mode == Mode.SEARCH) searchMenuItem.collapseActionView (); } Анимирование элементов Toolbar Для создания анимации я использовал библиотеку AndroidViewAnimations. Эта библиотека умеет анимировать любые объекты класса View или объекты классов, которые наследуются от View. Основная проблема с которой мы сталкиваемся когда хотим создать анимацию для элементов Toolbar это отсутствие объекта класса View. У нас есть только MenuItem элемента, который мы хотим анимировать.Если мы будем работать с MenuItem, который мы создали сами, к примеру иконкой поиска, то получить его View довольно легко:
MenuItem searchMenuItem = menu.findItem (R.id.action_search); View searchItemView = findViewById (searchMenuItem.getItemId ()); Всё усложняется, когда мы хотим получить View системного элемента Toolbar, к примеру стрелки «назад», которая становиться видна в режиме поиска (см. скриншот режима поиск). Поскольку мы не знаем id этой стрелки, нам придётся использовать Field, который позволяет нам получать динамический доступ к любому члену класса. В нашем случаи стрелка «назад» является членом класса Toolbar, но перед тем как мы начнём нам понадобиться узнать имя стрелки внутри класса. Идём в исходный код Android, открываем класс Toolbar и находим нашу стрелку на 100-й строчке под именем «mNavButtonView». Пример кода, в котором мы получаем View стрелки и анимируем его: // Получение View ImageButton btnToolbarButton = null; try { Toolbar mActionBarToolbar = (Toolbar) findViewById (R.id.toolbar_actionbar); Field fNavBtn = mActionBarToolbar.getClass ().getDeclaredField («mNavButtonView»); fNavBtn.setAccessible (true); btnToolbarButton = (ImageButton) fNavBtn .get (mActionBarToolbar); } catch (NoSuchFieldException e) { e.printStackTrace (); } catch (IllegalAccessException e) { e.printStackTrace (); } //Анимация if (btnToolbarButton!=null) YoYo.with (Techniques.FlipInX).duration (850).playOn (btnToolbarButton); Заключение В данной статье мы рассмотрели процесс создания динамического Toolbar и методы работы с его элементами. К сожалению в рамках одной статьи нельзя рассмотреть абсолютно все нюансы и разобрать весь код, поэтому если вам интересно узнать больше вы можете взглянуть на код приложения, которое мы использовали в качестве живого примера на GitHub.