Pull to refresh

Леденец из мороженого, или как привнести в ваше приложение немного Material

Reading time7 min
Views20K
Пятая версия Android была выпущена почти полгода назад. Несмотря на это, большинство приложений в маркете до сих пор упорствуют в стиле Holo. То ли новый Material-стиль пока не по зубам среднему разработчику, то ли Android L еще не успел прочно войти в обыденность.

Как бы там ни было, новая парадигма дизайна активно пропагандируется «корпорацией добра», да и выглядит достаточно неплохо, несмотря на некоторую непоследовательность. И все больше появляется добрых волшебников, помогающих нам, простым разработчикам, оставаться «в струе» изменчивого мира мобильного UI.

Если вы, как я недавно, твердо решили обернуть своё, давно не обновлявшееся, приложение в новую «шкурку», этот обзор инструментов и библиотек может сэкономить вам N часов времени.


Уже больше 3,5 лет я приобщаюсь к коллективному разуму Хабра. Чуть больше времени прошло с тех пор, как я впервые скачал и установил Android Development Kit. Думаю, настало время внести свою лепту.

Отдавая себе отчет, что подобные обзоры довольно быстро теряют актуальность, не написать его я не мог. Тому есть несколько основных причин:
  • работая над новым дизайном для своего приложения, я за два месяца перелопатил тонны гуглостраниц, по крупицам собирая ссылки на Github, которые в конце концов оказывались абсолютно бесполезными;
  • скоро лето, пора отпусков, а я прекрасно себе представляю, чем именно занимаются в отпуске (на больничном, etc) разработчики. Поэтому сейчас, думаю, самое время;
  • на данный момент на просторах интернета уже можно найти стилизации если не для всех, то для большинства элементов дизайна.

Дисклеймер
Конечно же, данный обзор не претендует на законченность, абсолютность и призыв к действию. Возможно, пока я это писал, Google выпустил общую библиотеку совместимости для всех элементов интерфейса.
Также возможно, что кому-то удобнее написать очередной велосипед, зато свой, с «Манчкином» и эльфийками…
Точно так же я не могу рекомендовать обязательно использовать представленные инструменты: почти все они распространяются с пометкой AS IS, и включать их в свой проект вы можете только на свой страх и риск.
Ну и последнее. Я все-таки (не без баттхёрта) перешел на Android Studio около полугода назад. И влюбился в эту среду разработки. Поэтому все способы включения библиотек в проект будут относиться к gradle. С Eclipse все и проще, и сложнее одновременно, и я буду считать, что разработчик знает, как подключить проект библиотеки в этой IDE.

Список элементов дизайна, подлежащих «ребрендингу», довольно длинный.
Поскольку много элементов (такие, например, как CheckBox и EditText) меняют стили автоматически при использовании AppCompat-темы, здесь мы рассмотрим следующие, не включенные в библиотеку совместимости, виджеты:
  • NavigationDrawer
  • FloatingActionButton
  • AlertDialog
  • ProgressBar
  • SeekBar


NavigationDrawer




Не знаю, как кому, а мне очень нравится этот элемент. Кроме того, он уже успел стать стандартным для Android, как и иконка-«гамбургер». Правда, здесь у Google не обошлось без косяков:
  • появился Drawer вместе с ActionBarDrawerToggle в виде съезжающих вбок трех полосочек;
  • изменилась ActionBarDrawerToggle («гамбургер», превращающийся в стрелочку, многим пришелся по душе);
  • правила для Drawer изменились вместе с концепцией Toolbar: теперь NavigationDrawer перекрывает заголовок приложения. Это привело к двум странным, на мой взгляд, последствиям — анимация ActionBarDrawerToggle теперь не видна (и вообще непонятно, зачем она), и закрыть меню мы можем только свайпом или системной кнопкой «назад».

Сразу оговорюсь — в своих приложениях я пока оставляю второй вариант (вернулся с третьего) — мне он кажется намного логичнее.

Сам Drawer включается в приложение легко, особенно, если проект создаётся с нуля. Просто выберите соответствующий вид приложения в мастере — и получите шаблон с активити, фрагментом и классом самого Drawer. Думаю, этот момент можно опустить — операция стандартная. Если же вы пытаетесь реорганизовать старое приложение, имейте в виду, что вам понадобится библиотека совместимости android-support-v4.

Привести ActionBarDrawerToggle в новый вид вам поможет библиотека appcompat-v7 (её, как и предыдущую, можно найти в директории extras вашего SDK).

Включить эти библиотеки в сборку своего модуля можно одной строкой в блоке dependencies файла build.gradle:

dependencies {
    compile 'com.android.support:appcompat-v7:22.0.0'
}

22.0.0 — номер текущей версии библиотеки (можно подсмотреть в SDK-менеджере, а можно поставить "+", и среда разработки будет использовать последнюю доступную версию, настойчиво предлагая вам все-таки проставить номер текущей версии, во избежание, так сказать...).

Для стилизации под новые гайдлайны (с меню во всю высоту экрана) придется немного попотеть. Во-первых, стандартный ActionBar нужно будет заменить на ToolBar, а во-вторых, добавить дополнительные элементы в стили приложения. Работающее решение найдено на Stackoverflow.

Если вам не хочется долго выставлять все отступы и HEX-коды цвета текста в самом меню, на Хабре можно найти инструкцию по использованию библиотеки, делающей это за вас. Комментарии к статье, как это часто бывает, очень ценны, рекомендую почитать. В любом случае, решать вам.

Еще одна кастомизация NavigationDrawer
Интересная библиотека встретилась мне, когда заказчик захотел размывать слой под меню во время открытия, вместо затемнения.

Из замеченных сложностей — если у вас в контенте прокручивающийся список, библиотека часто бывает неспособна отследить его состояние, и при открытии меню показывает размытие «старого» контента, в то время как реально список уже другой. Но внимания, определенно, стоит.

FloatingActionButton




Еще один новый элемент UI. Очень помогает выделить одно (или несколько) основное действие на экране, и обратить на него внимание пользователя.
К сожалению, в библиотеку поддержки этот элемент не входит (как и множество других), поэтому в данном случае нам придется использовать сторонние решения.
Их я выделил несколько, и по каждой напишу пару мыслей, возникших при их использовании.
  • Решение от уважаемого John Hogan, описанное на Хабре. Выделю два попавшихся неудобных момента:
    1. нужно включать код в свой проект, что ухудшит читаемость;
    2. обработку исчезновения/появления разработчик оставил нам;
    В целом же — можно просто брать и использовать.
  • Данная библиотека. Неплохо реализованы «вложенные» кнопки, но имеет «фатальный недостаток»: очень ограничена работа с самой кнопкой, практически — только клики. Само собой, нет и «слушателя», позволяющего автоматически убрать/показать кнопку при, например, прокрутке ListView.
  • Вот это решение. Очень неплохая, как по мне, реализация. Есть два размера (напомню, что мини-кнопка используется, как вспомогательное действие при просмотре контента), довольно оригинально «пристыковывается» к прокручиваемым элементам для автоскрытия, имеет гибкие настройки через файл разметки. Единственная проблема, на которую я наткнулся — невозможность подружить эту кнопку с другим кастомным OnTouchListener. Для меня это было критично, поскольку я использую swipe-to-dismiss в своих ListView.
  • Выбранная мной для своего проекта. Простая, настраиваемая, не конфликтует с OnTouch, встраивается в два клика.
  • Эта библиотека найдена уже в процессе подготовки статьи, поэтому не тестировалась мною. Если кто-то может дать по ней информацию — пожалуйста, пишите в комментариях, и я добавлю её в статью.

Как видите, выбирать есть из чего.

AlertDialog




Каждый разработчик когда-либо пользовался этим виджетом. Мне лично очень не нравился стиль диалогов в 4-х версиях Android, как и сам код, который приходилось писать для AlertDialog-ов.

AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setTitle("Alert title");
    alertDialogBuilder.setMessage("Alert message");
    alertDialogBuilder.setPositiveButton("Ok",
        new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface arg0, int arg1) {
        }
    });
    alertDialogBuilder.setNegativeButton("Cancel",
        new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface arg0, int arg1) {

        }
    });
    AlertDialog alertDialog = alertDialogBuilder.create();
    alertDialog.show();

Конечно, с помощью Retrolambda и цепочки вызовов это можно немного «причесать» и сократить. Но код все равно остается, с вашего позволения, немного неаккуратен.

Библиотек, реализующих данный виджет в Material-стиле, довольно много, и они достаточно похожи:

ProgressBar




Очень красивыми стали и прогресс-бары в новой версии Android.
Так уж получилось, что в моем приложении этот элемент используется часто — много работы с фото, много тяжелых сетевых запросов. Поэтому к выбору ProgressBar я подходил долго и упорно. Но искал я обычный Circular виджет, без излишеств — все-таки это стилизация, а не полностью новая парадигма. И оказалось, что обычных круговых указателей прогресса как-то мало…
Для себя я выбрал две библиотеки. Первую отсеял из-за не совсем корректной инициализации из кода. Вторую использую и сейчас.

SeekBar




С этим виджетом у меня связаны не очень приятные воспоминания. Дело в том, что по старой компоновке экрана в моем приложении при использовании альбомной ориентации мне нужны были вертикальные SeekBar-ы.
Не спрашивайте.

Так вот, если для Holo-тем я такие виджеты нашел, то для Material и обычных-то немного. Но, в конце концов, это натолкнуло меня на небольшую перекомпоновку экрана, так что я даже благодарен SeekBar-у за это.

Сейчас для этого элемента я использую DiscreteSeekBar. Несмотря на то, что библиотека пока очень молодая, и даже не присутствует в jcenter, меня она устраивает полностью: мощная кастомизация, удобная реализация слушателя, использование Animatable Drawable, что позволяет работать довольно шустро и без тормозов.

Кроме того, это почти единственная библиотека по этому виджету. Есть еще MaterialRangeBar, но она не реализует простого SeekBar, поэтому мне не подходит.
(Еще об одной реализации я расскажу чуть ниже, как и о причинах, почему она меня не устроила.)

Если вам интересно, что получилось у меня в итоге — под спойлером кликабельные сравнительные скриншоты старой и новой версий.

Вот они, скриншоты











На сладкое


В поисках библиотек для SeekBar я наткнулся на вот этот репозиторий. И совсем было подумал, что мне не нужны все вышеописанные украшательства — хватит одной этой библиотеки. Серьезно, там есть все, что мне нужно (да и подавляющему большинству разработчиков, скорее всего).

Но все не так радужно. Проект очень молодой, и всё ещё в разработке (например, для SeekBar пока даже не реализован onSeekChangeListener). Поэтому пользоваться им сейчас я бы не рекомендовал. А вот что рекомендовал бы, так это посильную помощь данной библиотеке — багрепортами, фича-реквестами и кодом. Сам собираюсь. Это может очень сильно облегчить жизнь как начинающим программистам, так и тем, кто уже заматерел настолько, что писать свои велосипеды влом.

В общем, подключайтесь!

Спасибо всем, кто дочитал до конца. Специально для таких вот терпеливых и въедливых — несколько очень полезных ссылок:


Поменьше вам велосипедов в программировании!
Tags:
Hubs:
+20
Comments19

Articles

Change theme settings