- PVSM.RU - https://www.pvsm.ru -

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

Пятая версия Android была выпущена почти полгода назад [1]. Несмотря на это, большинство приложений в маркете до сих пор упорствуют в стиле 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

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

Не знаю, как кому, а мне очень нравится этот элемент. Кроме того, он уже успел стать стандартным для 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 [2].

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

Еще одна кастомизация NavigationDrawer

Интересная библиотека [5] встретилась мне, когда заказчик захотел размывать слой под меню во время открытия, вместо затемнения.

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

FloatingActionButton

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

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

  • Решение от уважаемого John Hogan, описанное на Хабре [6]. Выделю два попавшихся неудобных момента:
    1. нужно включать код в свой проект, что ухудшит читаемость;
    2. обработку исчезновения/появления разработчик оставил нам;

    В целом же — можно просто брать и использовать.

  • Данная библиотека. [7] Неплохо реализованы «вложенные» кнопки, но имеет «фатальный недостаток»: очень ограничена работа с самой кнопкой, практически — только клики. Само собой, нет и «слушателя», позволяющего автоматически убрать/показать кнопку при, например, прокрутке ListView.
  • Вот это решение. [8] Очень неплохая, как по мне, реализация. Есть два размера (напомню, что мини-кнопка используется, как вспомогательное действие при просмотре контента), довольно оригинально «пристыковывается» к прокручиваемым элементам для автоскрытия, имеет гибкие настройки через файл разметки. Единственная проблема, на которую я наткнулся — невозможность подружить эту кнопку с другим кастомным OnTouchListener. Для меня это было критично, поскольку я использую swipe-to-dismiss в своих ListView.
  • Выбранная мной для своего проекта. [9] Простая, настраиваемая, не конфликтует с OnTouch, встраивается в два клика.
  • Эта библиотека [10] найдена уже в процессе подготовки статьи, поэтому не тестировалась мною. Если кто-то может дать по ней информацию — пожалуйста, пишите в комментариях, и я добавлю её в статью.

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

AlertDialog

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

Каждый разработчик когда-либо пользовался этим виджетом. Мне лично очень не нравился стиль диалогов в 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

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

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

SeekBar

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

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

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

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

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

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

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

Леденец из мороженого, или как привнести в ваше приложение немного Material - 6 [21] Леденец из мороженого, или как привнести в ваше приложение немного Material - 7 [22]
Леденец из мороженого, или как привнести в ваше приложение немного Material - 8 [23] Леденец из мороженого, или как привнести в ваше приложение немного Material - 9 [24]
Леденец из мороженого, или как привнести в ваше приложение немного Material - 10 [25] Леденец из мороженого, или как привнести в ваше приложение немного Material - 11 [26]
Леденец из мороженого, или как привнести в ваше приложение немного Material - 12 [27] Леденец из мороженого, или как привнести в ваше приложение немного Material - 13 [28] Леденец из мороженого, или как привнести в ваше приложение немного Material - 14 [29]

На сладкое

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

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

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

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

  • Awesome Android [31] — огромнейший сборник библиотек. Найдется [почти] все.
  • Polymer project [32] — проект полной кастомизации интерфейса. Выглядит очень круто.
  • Libraries for developers [33] — приложение на Google Play, созданное для разработчиков, эдакий справочник по библиотекам. Позволит вам «пощупать» их вживую.

Поменьше вам велосипедов в программировании!

Автор: formatbce

Источник [34]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/ui/88538

Ссылки в тексте:

[1] почти полгода назад: http://en.wikipedia.org/wiki/Android_Lollipop

[2] на Stackoverflow: http://stackoverflow.com/a/26440880/1259029

[3] все отступы и HEX-коды цвета текста в самом меню: http://www.google.com.ua/design/spec/patterns/navigation-drawer.html

[4] инструкцию по использованию библиотеки: http://habrahabr.ru/post/250765/

[5] Интересная библиотека: https://github.com/charbgr/BlurNavigationDrawer

[6] описанное на Хабре: http://habrahabr.ru/post/231429/

[7] Данная библиотека.: https://github.com/futuresimple/android-floating-action-button

[8] Вот это решение.: https://github.com/shamanland/floating-action-button

[9] Выбранная мной для своего проекта.: https://github.com/makovkastar/FloatingActionButton

[10] Эта библиотека: https://github.com/shell-software/fab

[11] github.com/drakeet/MaterialDialog: https://github.com/drakeet/MaterialDialog

[12] github.com/lewisjdeane/L-Dialogs: https://github.com/lewisjdeane/L-Dialogs

[13] github.com/fengdai/AlertDialogPro: https://github.com/fengdai/AlertDialogPro

[14] github.com/avast/android-styled-dialogs: https://github.com/avast/android-styled-dialogs

[15] даже вот такое: https://github.com/pedant/sweet-alert-dialog

[16] Выбранная мной библиотека.: https://github.com/afollestad/material-dialogs

[17] github.com/rahatarmanahmed/CircularProgressView: https://github.com/rahatarmanahmed/CircularProgressView

[18] github.com/pnikosis/materialish-progress: https://github.com/pnikosis/materialish-progress

[19] DiscreteSeekBar: https://github.com/AnderWeb/discreteSeekBar

[20] MaterialRangeBar: https://github.com/oli107/material-range-bar

[21] Image: https://habrastorage.org/files/0f4/3d3/032/0f43d30324de48fb9c9d9952691353e3.png

[22] Image: https://habrastorage.org/files/a02/5ac/1ef/a025ac1ef045485cbff5670229396c03.png

[23] Image: https://habrastorage.org/files/608/7f4/710/6087f471010f450a86de09151d87ed82.png

[24] Image: https://habrastorage.org/files/c19/f01/637/c19f016375334d5cb5ec1ba669c25afa.png

[25] Image: https://habrastorage.org/files/df7/3d6/dab/df73d6dabfa9424e8e64cf9f22b554db.png

[26] Image: https://habrastorage.org/files/12e/414/a79/12e414a7999c40068d93715cd1f73e3b.png

[27] Image: https://habrastorage.org/files/2af/2d5/089/2af2d5089c374611a8ccb683a72d8ea2.png

[28] Image: https://habrastorage.org/files/68d/e4f/484/68de4f484c864020b588bb313c34f2eb.png

[29] Image: https://habrastorage.org/files/7f0/649/470/7f064947067746da9ddbf3cba354a7b5.png

[30] вот этот репозиторий: https://github.com/rey5137/material

[31] Awesome Android: http://snowdream.github.io/awesome-android/

[32] Polymer project: https://www.polymer-project.org

[33] Libraries for developers: https://play.google.com/store/apps/details?id=com.desarrollodroide.repos&hl=en

[34] Источник: http://habrahabr.ru/post/255455/