Внедряем материальный дизайн
Настало время переходить на Lollipop, друзья. Как бы смешно это не звучало.
Буквально вчера мы в Surfingbird обновили дизайн приложения и сегодня, по свежим следам, хотелось бы поделиться впечатлениями от перехода на material design.
Чтобы минимизировать количество проблем, лучше обновить все)
- Устанавливаем образ lollipop на свой
нексустелефон - Обновляем Java до 7 версии, если еще нет
- Обновляем IDE, мы используем Intellij Idea
- Обновляем SDK, не забудьте обновить Tools, Platform-tools, Build-tools, Sdk и Support library
RecyclerView это новый ViewGroup компонент, который пришел на замену List/GridView. Но он не является их потомком, скорее это альтернативная ветвь эволюции. С одной стороны, это гораздо более гибкий и более эффективно работающий компонент, с другой — в нем из коробки отсутствуют, либо делаются по другому некоторые вещи, к которым мы привыкли в List/GridView (разделители, быстрый скролл, селекторы, хидеры и т.п.).
Во-первых, по субъективным ощущениям, скроллинг стал более плавным, чем при использовании listview+viewholder, во-вторых, появилось множество прекрасных штук, так что игра несомненно стоит свеч.
Перейти на этот компонент очень просто. Закидываем в библиотеки соответствующий sdk ▸ extras ▸ android ▸ support ▸ v7 ▸ recyclerview ▸ libs▸ android-support-v7-recyclerview.jar/подключаем в богомерзком gradle или чем вы пользуетесь.
1. Обновляем адаптер, если вы уже использовали view-holder паттерн, то все привычно
Заменяем BaseAdapter(или что там у вас было) на RecyclerView.Adapter
В onCreateViewHolder — парсим layout
где, собственно ViewHolder – привычная заглушка
и переносим логику наполнения view из getView в onBindViewHolder (обращаясь к холдеру — holder.stgvImageView и т.п.)
Удаляем ставшие ненужными методы типа getItem
2. Заменяем ListView на RecyclerView
3. Продолжаем разговор.
Работа с адаптером практически не изменилась.
Стал ненужным метод отключения адаптера на момент изменения (DataSetInvalidated), нотификация об изменении осталась без изменения
Изменился метод вычисления последнего видимого элемента (для автоматической подгрузки следующей порции). Предполагаю, что эту логику лучше перенести в адаптер, но, если очень некогда, то можно так, например:
Вообще, скролинг стал более низкоуровневым, теперь можно прямо в этом методе получать информацию куда и насколько проскролено (простите мой английский)
На этом месте у вас все должно заработать. Если, например, нужно добавить разделители, то их можно добавить перекрыв класс DividerItemDecoration, например так: (вертикальные разделители)
(Ахтунг, копипаста сами знаете с какого сайта)
Но не спешите с этим! Потому что появились прекрасные Карточки!
Помню, когда я был еще совсем молодым android-разработчиком, вышел пинтерест и все офигели. Мы часами разглядывали, как они реализовали карточки переменной высоты, плавающие кнопки (или это было в Path?), не суть важно. Сейчас можно получить неплохо выглядящие карточки (в том числе, переменной высоты и прямо как в пинтерест) буквально в пару строк кода.
Подключаем cardview как library project/прописываем магическую строку в систему сборки, закидываем jar, не забыв обновить версию саппорт лайбрари.
По сути, карточки — это фрейм вокруг вашего лейаута с тенюшками и скругляшками, поэтому просто обрамляем ими ваш лэйаут:
Теперь, допустим, для планшетной версии задаем отображение в две колонки, а для телефонов в одну:
(Ахтунг, копипаста сами знаете с какого сайта)
И задаем для разных устройств разный формат отображения:
Должно получиться примерно так:
- После того, как мы выложили приложение в стор, на некоторых устройствах (почему-то на нексусах) и почему-то в том числе на 4.4.4 – приложение странным образом начало падать в районе саппорт лайбрари (причем на наших телефонах (включая нексусы) все работало). Пришлось отключить proguard, это помогло но осадок остался.
- Нам не очень понравился цвет шрифта в дефолтной светлой теме. Он очееень нежен, учитывая то, что на всех андроид устройствах цветопередача нарушена разная, поэтму мы решили перекрыть цвет шрифта на чуть более темный.
- Отключить тень у акшенбара теперь можно, например, так: getSupportActionBar().setElevation(0);
- Приложение не будет работать на бете лоллипоп так же, как не работают на ней и все остальные приложения в лоллипоп дизайне (gmail, пресса)
- Иконки акшенбара стали меньше. Мы просто перенесли их в папку (xxhdpi)
- Мы пока решили забить на анимации. Перед глазами гугл-пресса и все вроде дико красиво крутится/вертится/плавает/мигает, но мы еще не готовы к такой решительной анимации.
Глаз разработчика «замылен», сложно сказать получилось хорошо или так себе. Я почему-то ожидал большего, если честно. Динамически падающих тенюшек при скролинге, например, больше магии. А в целом, все получилось чуть свежее. Хотя, конечно, мы еще не до конца ололлипопились. Посмотреть результат можно в маркете.
Я наверняка что-то забыл. Делитесь нюансами, рецептами и советами перехода на лоллипоп в комментариях. Тема актуальная, всем нам будет полезно и интересно.
Источник
14 октября 2014 г. Android Material Design
Всем доброго времени суток! Думаю, все смотрели презентацию Android L и видели его революционный для платформы Material Design. Что ж, релиза осталось ждать недолго, а тем временем внимательные пользователи могли заметить появление элементов нового дизайна в некоторых приложениях. Моё внимание приковало к себе обновление «Play Пресса». Выглядит и ощущается действительно революционно, я залип на несколько минут и даже начал читать прессу.
Каждый раздел сопровождается анимированным фоном, который плавно слайдится и, растворяясь, меняет изображения. Много необычных анимаций, которые привносят некоторую свежесть в приложение.
Естественно, у каждого разработчика при виде всех этих сластей возникает желание воплотить данные решения в своих проектах. К сожалению, на момент презентации доступные гайдлайны и документация не пестрили подробностями, они скорее напоминали рекламный прейскурант. К счастью, Google на момент написания статьи удосужились исправить ситуацию, и мы посмотрим что у них получилось.
Итак, гайдлайны достаточно кратко и лаконично описали философию Material Design, советую всем прочитать во избежание ошибок в дальнейшем, дублироваться здесь не буду. Единственное: интригует надпись «This document is a preview», что указывает на то, что, возможно, это еще не конечный вариант.
Далее документация. Что же нам обещают в новой версии? Если вкратце, то все сводится к новой теме, новым виджетам, кастомным теням и анимациям.
Тема Material
Новая тема добавит новые стили для старых виджетов, анимации откликов на касания к элементам интерфейса, новые анимации перехода между активностями. А что нам еще нужно?!)
Новые виджеты
RecyclerView, по сути, есть логическим продолжением самого востребованного в Android-разработке виджета — ListView. Собственно, предназначение у него ровно то же самое — отображать список элементов, но есть нюансы.
Обязательное использование паттерна ViewHolder. Если при использовании ListView можно было из-за отсутствия опыта использовать адаптер, создающий с нуля отдельное view для каждого элемента списка, что при большом размере списка могло обернуться меньшей отзывчивостью UI и использованием лишней памяти, то при работе с RecyclerView разработчика насильно приводят к имплементации этого паттерна. Посмотрим, как это выглядит в коде адаптера для RecyclerView.
LayoutManager. Для использования RecyclerView кроме адаптера вам необходимо передать ему с помощью метода setLayoutManager() объект класса, реализующего LayoutManager. Этот класс отвечает за работу с адаптером, именно он решает, повторно использовать View или создать новый, и соответственно, именно он дёргает методы onCreateViewHolder(), onBindViewHolder() и getItemCount() адаптера. Пока доступна только одна реализация этого класса — LinearLayoutManager, для создания кастомного LayoutManager необходимо унаследоваться от RecyclerView.LayoutManager.
Анимация операций со списком. Если вы смотрели презентацию дизайна Material, то могли заметить, что одной из основных его особенностей является плавность UI, которая достигается с помощью повсеместного использования анимации. Наверняка, при особом желании можно добавить анимацию и в ListView, мне пока не приходилось этим заниматься, но в RecyclerView это делается парой строчек кода.
Для объекта RecyclerView указывается класс, имплементирующий анимацию:
При добавлении или удалении элемента списка вызывается метод адаптера notifyItemInserted(int position) или notifyItemRemoved(int position) соответственно.
При желании можно написать собственную реализацию анимации, унаследовавшись от RecyclerView.ItemAnimator.
Сырость. Нужно помнить, что виджет пока сыроват, и, возможно, его ждут существенные изменения. Например, сейчас в RecyclerView нет возможности задать header и footer списка, да и вообще в интернете о нём пока довольно мало информации.
CardView — это виджет, имплементирующий такой элемент дизайна Material, как карточка. По сути, это контейнер, у которого можно задавать радиус округленности углов, цвет карточки и высоту по оси z.
Отображение теней
Интересным нововведением, исповедующим Material-философию, является отрисовка теней. Я себе это представил так: если элементы интерфейса являются материальными, они должны отбрасывать тень. А какой размер у этой тени должен быть? Естественно, он будет зависеть от расположения элемента относительно фона и других элементов. Потому у виджетов появился новый параметр, раньше мы им задавали лишь размеры по X и Y, теперь же высоту по Z. Таким образом, виджет, находящийся на более высоком уровне, будет отбрасывать большую тень.
Данный параметр называется android:elevation и применяется так:
С помощью такого решения еще и реализуется управление многослойностью нашего интерфейса, виджеты могут сдвигаться друг на друга, отбрасывая соответствующую тень, перекрывая частично или полностью слои находящиеся под ними. Выглядит это очень эффектно и материально, напоминая коллаж или аппликацию, сшитую из элементов интерфейса.
Анимации
Анимации действительно претерпели больших изменений, и те, кто смотрел гайдлайны, со мной согласятся, а те, кто еще не смотрел — уже побежали это делать).
В новом API нам предоставляют новые анимации отклика на касания пользователя, новые анимации изменения состояния отдельных виджетов и анимации смены активностей. Кратко пройдёмся по каждой группе.
Touch Feedback. Новая анимация отклика на касание, заключается в выделении точки координат, на которую нажал пользователь, и дальнейшем эффекте волны от этой точки по всем направлениям. Анимация имеет логические начало и завершение, выглядит потрясающе и призвана заменить старые селекторы. Реализуется с помощью класса RippleDrawable. Можно реализовать как в xml, так и в коде применить к своему view. Пример реализации в xml, устанавливается как backround:
Существует реализация данного класса для предыдущих версий, её можно посмотреть на github.
Reveal Effect. Данный эффект позволяет красиво показывать и прятать вьюхи, реализуется с помощью класса ViewAnimationUtils.createCircularReveal, для объяснения приведу примеры, взятые из документации.
Чтобы показать ранее скрытый вью:
Чтобы скрыть ранее показанный вью:
Activity Transitions. Здесь тоже не обошлось без изменений, и Google добавил понятие «общего» элемента между активностями. То есть во время анимации перехода между активностями у нас есть некоторый элемент, который, не покидая экран, может менять своё местоположение и размеры — выглядит прикольно.
Все анимации переходов описываются в стилях, элементы же передаём параметром в интент:
Можно передать несколько параметров, если мы используем несколько общих вью:
Curved Motion. Все анимации в Material должны происходить плавно, и дифференцироваться во времени, то есть изменять свою скорость. Ранее все было не так, если какая-то анимация начиналась с определенной скоростью, она с ней и завершалась; теперь же, если представить развитие событий в виде графика, он будет напоминать параболу с приплюснутой вершиной. Данное пояснение можно наблюдать на видео в гайдлайнах.
Создавать такие анимации нам помогут классы PathInterpolator и ObjectAnimator, первый используется при анимировании в xml ресурсах, второй же прямо в коде:
Animating View State Changes. Анимация изменения состояний наших вью производиться с помощью продвинутого селектора и класса StateListAnimator.
Также появился вариант анимированого селектора:
Extracting Prominent Colors from an Image. Появился мощный инструмент дизайна в реалтайме, это класс Palette, который возвращает преобладающий цвет из переданного эму изображения, что позволяет в дальнейшем применить маску для этого же изображения для нанесения на неё текста, или в каких-либо иных целях. Таким образом, палитра, которую использует ваш дизайн, может подстраиваться под контент в реалтайме, данный кейс используется в Material версии Play Музыка и выглядит действительно круто.
Рассуждения
К сожалению, не все так радужно, и здесь есть своя ложка дегтя. Практически все нововведения нам доступны только в версии L-preview, потому воспользоваться ими с ходу не получится. Для того, чтобы получить такую возможность, нам нужно использовать последнюю версию Android Studio с новым манифест мержером, это утилита, которая позволяет более гибко контролировать процесс «сшивания» всех манифестов библиотек, задействованных в проекте.
Подключаем новую xml-схему под названием tools:
Переопределим версию, которая в конечном итоге будет подтягиваться в build.gradle файла:
Добавляем библиотеки в зависимости:
Таким образом, мы можем уже использовать новые виджеты, но их функционал будет урезан. Что касается темы, она будет доступна только в API версии 21. Написав приложение с использованием нового SDK на девайсе с kitkat, мы увидим, что практически ничего не изменилось, а установив в это же приложение L-preview, все должно приобрести соответствующий вид — ключевое слово «должно», так как на текущий момент все жутко крашится. Можно, конечно, попытаться все исправить, но отсутствие поддержки темы в старых версиях напрочь убивает всякую охоту этим заниматься.
Вывод: Play Пресса — попытка Google адаптировать данное приложение к переходу на новый API, использовав в нём новые виджеты, и придать вид, схожий с Material, задействовав старые инструменты. Возможно, это было сделано для того, чтоб поэкспериментировать с поддержкой новой версии, но пока Play Пресса не готова к этому, так как после установки на Nexus 5 L-preview она тоже крашнулась.
Что касается новых возможностей, то они туманны. Если Google не сделает нормальную поддержку предыдущих версий, а линейка девайсов, которые получат новое обновление, в скором времени не пополнится самыми популярными девайсами других производителей, то следующие полгода наши труды с новым дизайном и не только сможет оценить очень малый процент пользователей. Ну, а я, как всегда, надеюсь на лучшее :).
Источник