В мобильном приложении все должно быть прекрасно — и Java-код с паттернами, и UI. И если мобильный backend, кроме создателя, никто не видит, то создать удобный, яркий и, конечно же, модный интерфейс — дело необходимое и сложное. Зная об этом, летом компания Google анонсировала появление нового способа верстки пользовательских интерфейсов. Нововведения содержатся в классе ConstraintLayout, предполагается, что он не только упростит передачу мыслей дизайнеров разработчикам, но и повысит скорость работы приложения. Давай разберемся, как много в этих словах правды и где ждать подвохов.

 

View и ViewGroup

Чтобы правильно оценить нововведения, нужно понять, с чем мы вообще имеем дело. Java — классический ООП-язык, в котором важную роль играет принцип наследования. В Android у всех визуальных элементов есть базовый класс-прародитель — View. От него напрямую унаследованы все те многие элементы интерфейса, которые разработчик помещает на экране: TextView, ImageView и прочие. Для их корректного отображения на экране во View уже созданы все необходимые методы для отрисовки элемента: onDraw, getPadding и другие.

Но элементы класса View нельзя разместить на экране просто так, их нужно чем-то сгруппировать. Для компоновки элементов, создания из них единой, органичной картины в Android созданы макеты (layouts). Именно они позволяют размещать элементы так, чтобы они радовали глаз каждого хипстера :).

Для макетов создан отдельный родительский класс — ViewGroup, в котором собраны все необходимые для макета параметры. Макетов в Android много, самые распространенные — LinearLayout и RelativeLayout.

Отображаемые пользователю элементы приходится хранить в оперативной памяти устройства, что весьма затратно. Поэтому система старается побыстрее выгрузить оттуда ненужное, а новые объекты добавлять в последний момент. При этом объекты на экране отрисовываются не случайным образом, а в порядке их старшинства в иерархии наследования. Все видимые пользователю объекты класса View будут обработаны ОС в последнюю очередь, поэтому-то пользовательские интерфейсы и «подвисают».

 

Layout

Макеты в Android не живут своей жизнью, а привязаны к базовым компонентам приложения — Activity. Именно объекты этого класса хранят информацию о визуальных элементах, подготовленных для показа пользователю. Данные о UI передаются в Activity с помощью метода setContentView. Как правило, он вызывается сразу же при создании объекта, в методе onCreate.

setContentView(R.layout.activity_main);

Файл activity_main хранит в себе всю достаточную информацию о пользовательском интерфейсе, это и есть готовая верстка интерфейса приложения. В мире Android это конфиг в формате XML, расположение элементов в нем задается параметрами внутри тегов, а также может зависеть от позиции в файле.

<RelativeLayout...>
  <TextView ... android:layout_centerVertical="true"/>
  <ImageView ... android:layout_alignParentRight="true"/>
</RelativeLayout>

Актуальные версии Android позволяют достаточно гибко обращаться с элементами интерфейса: можно использовать одну и ту же верстку несколько раз или создавать контейнеры с динамически подгружаемым содержимым. Конечно, такие конфигурационные файлы можно генерить программно, внутри Activity или где-то еще.

LinearLayout linLayout = new LinearLayout(this);
linLayout.setOrientation(LinearLayout.VERTICAL);
// Задаем параметры макета и добавляем элементы
...
setContentView(linLayout, linLayoutParam);
 

Установка

Новый макет был представлен публике в мае 2013 года. И хотя стабильная версия все еще не появилась, интерес к предложенному инструменту в среде Android-разработчиков не угасает. Есть ощущение, что компания Google делает большую ставку на этот макет и в будущем он может стать стандартом при разработке интерфейсов.

На первый взгляд — революции не произошло. Новый класс все так же унаследован от ViewGroup, однако создатели обещают, что работать с ним будет быстрее и легче. Все запланированные бонусы при работе с ConstraintLayout разработчик почувствует, только установив свежую Android Studio. Официально версия 2.2 пока еще не вышла, на момент написания статьи был доступен билд Release candidate 2. Это уже очень близко к стабильной версии, а значит, можно качать по ссылке внизу статьи и осваивать.

Устанавливается IDE по-прежнему быстро и просто, спасибо создателям. Возможно, тебе потребуется обновить версию сборщика Gradle, на официальном сайте доступна версия 3.0. Сложностей тоже быть не должно — просто скачай самую свежую версию, а затем укажи путь к папке в настройках студии.

 

ConstraintLayout

Сейчас новый макет доступен в виде отдельной библиотеки, подключаемой через Gradle.

compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha5'

Такой вариант дистрибуции выбран не просто так — ConstraintLayout совместим со всеми версиями Android начиная с 2.3. Это очень круто, поскольку RelativeLayout иногда некорректно работает в версиях Android ниже 4.2, а значит, в перспективе ConstraintLayout может выручить в подобных случаях, с которыми раньше справиться было трудно.

Способ создания новых проектов не поменялся (это же не Microsoft Office), но слегка изменился дизайн интерфейсов. В своем «Hello, world» сразу переходи к activity_main. На вкладке Text будет верстка на основе ConstraintLayout, примерно такая.

<android.support.constraint.ConstraintLayout ... >
...
</android.support.constraint.ConstraintLayout>

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

 

Design

В новой студии обновлен графический редактор интерфейсов, который теперь называется просто Design. Его предшественник носил скорее декоративную функцию, пользы от него было мало. ConstraintLayout покажет все свои возможности только в связке с Design, вот почему столько приготовлений всего лишь из-за нового макета.

Рис. 1. Новый инструмент Design
Рис. 1. Новый инструмент Design

И вот он, обещанный drag’n’drop! В новом редакторе Google тебе представилась возможность создавать UI исключительно с помощью мышки. TextView, ImageView, FAB и прочие элементы, даже кастомные, теперь можно (и нужно) передвигать мышкой и компоновать их между собой линиями связи. У программиста наконец-то есть возможность создать что-то осмысленное, не написав ни строчки кода. Если ты не поленился и установил новую студию, рекомендую немного попрактиковаться, а я продолжу рассказывать о возможностях вкладки Design.

 

Связи и ограничения

Constraint переводится с английского как ограничение, напряженность. Именно такие ограничения теперь придется задавать каждому элементу, указывая на опорные точки. В ConstraintLayout есть несколько видов опорных точек для View-объектов:

  • другой визуальный объект;
  • край макета;
  • невидимая линия (guideline).

Как ты уже мог догадаться, объекты при верстке позиционируются относительно друг друга, это очень похоже на философию RelativeLayout.

Визуальный редактор Design показывает UI одновременно в двух режимах: слева максимально похоже на то, что увидит пользователь, справа — со всеми связями между объектами. Добавить новый элемент можно мышкой, перетащив его из раздела Palette в редактор.

Хорошая новость — с новым редактором стало гораздо легче выстраивать элементы. Прежде было достаточно хлопотно выровнять, к примеру, textView и imageView так, чтобы не было «провисаний». Новая студия сама предложит несколько вариантов позиционирования, достаточно немного «пошевелить» объект.

Рис. 2. Выравнивание элементов
Рис. 2. Выравнивание элементов

Кроме других объектов и краев макета, теперь добавился еще один элемент — невидимая линия (invisible guideline). Их может быть несколько, как вертикальных, так и горизонтальных. Предназначение — создать своеобразную сетку на экране, чтобы элементы можно было помещать в образовавшиеся «ячейки». Координаты линий можно задавать как точными смещениями, так и в процентах, что, несомненно, практичнее. В перспективе это может быть очень удобным инструментом.

К счастью, изменения в визуальном редакторе идентичны тем, что происходят в уже привычном XML-конфиге. Можно переключиться на вкладку Text и подправить то, что мы натыкали мышкой, а затем переключиться обратно на вкладку Design, где автоматически добавятся внесенные правки.

Как показал опыт работы в новом редакторе, теперь при создании более-менее сложных интерфейсов есть смысл начинать создавать элементы с середины экрана, а затем прикреплять остальные «сверху» и «снизу». Процесс соединения элементов сопровождается анимацией и в первое время радует глаз. Рекомендую попробовать, это действительно интересно.

 

Производительность

Когда Google презентовала RelativeLayout, разработчиков настоятельно просили использовать этот класс осторожно и только в тех местах, где он необходим. Это объяснялось сложностью его реализации и, как следствие, повышенным расходом ресурсов при отрисовке элементов.

В случае с ConstraintLayout все по-другому. Создатели обещают не только упрощенный способ верстки, но и возросшую производительность! Оптимистичное заявление, давай проверим, как с этим обстоят дела на практике.

Для формирования в оперативной памяти ОС готовых к отображению картинок у всех наследников View поочередно вызываются методы measure, layout и draw. От того, как быстро они отработают, напрямую зависит легкость и плавность работы UI. В Android есть несколько способов замерить скорость работы приложения, для тестирования UI подойдет утилита Hierarchy Viewer. Она поставляется вместе с SDK и работает как отдельное приложение.

android-studio-sdk/tools/./hierarchyviewer

Запустить утилиту нужно в тот момент, когда на эмуляторе (или живом устройстве) активно предназначенное к тестированию Activity. Программа построит граф связи всех визуальных элементов и, самое главное, покажет, как быстро был обработан тот или иной элемент. Я решил сравнить производительность ConstraintLayout и RelativeLayout, а для теста выбрал несложную верстку: ImageView и три TextView рядом. В RelativeLayout верстка выглядит так.

<RelativeLayout ... >
  <ImageView android:layout_alignParentLeft="true" ... />
  <TextView android:layout_toRightOf="@+id/image" ... />
  <TextView android:layout_below="@id/image" ... />
  ...
</RelativeLayout>

С использованием ConstraintLayout мне удалось набросать такой же вариант UI, не прибегая к вбиванию кода. Правда, времени это заняло столько же, как и при работе с RelativeLayout, — к визуальному редактору еще нужно привыкнуть.

<android.support.constraint.ConstraintLayout ... >
  <ImageView android:scaleType="centerCrop" ... />
  <TextView app:layout_constraintTop_toBottomOf="@+id/textView5" ... />
  <TextView app:layout_constraintTop_toBottomOf="@+id/imageView" ... />
  ...
</android.support.constraint.ConstraintLayout>
 

Результаты

Чтобы Hierarchy Viewer измерил затраченное ОС время, нужно нажать клавишу Profile node. Надо сказать, результаты получились странные. Если время рендеринга View-объектов примерно одинаково вне зависимости от верстки (что логично: их код никто не правил), то времени на макет с ConstraintLayout тратится существенно больше, чем на верстку со старым RelativeLayout.

Заметное падение производительности происходит в методе onMeasure, тут ConstraintLayout медленнее в полтора-два раза. Вполне логично, это следствие всех этих сложных связей между объектами, так как ОС требуется больше вычислений для позиционирования объектов. Если проводить серию тестов, то RelativeLayout снова впереди: отклонение от средних значений минимально, тогда как ConstraintLayout очень нестабилен.

Напомню, что сейчас новый макет поставляется как библиотека и находится в стадии alpha, очень далекой от релиза. Скорее всего, ребята из Google тщательно работают над оптимизацией, чтобы оправдать выданные авансы. Что же, пожелаем им здоровья, удачи и будем ждать существенных изменений в официальном релизе.

 

Впечатления

За тестированием ConstraintLayout я провел несколько вечеров, и у меня сложились двойственные впечатления. С одной стороны, серьезно снизился порог сложности для создания интерфейсов в стиле material: не нужно специальной подготовки, просто кликай мышкой и получай результат. И результат получается мгновенно, ты чувствуешь себя умным и успешным.

В то же время интерфейс редактора быстро перегружается мелкими деталями: обилие стрелок, черточек, анимации... и, кстати, сочетание клавиш Ctrl-z почему-то не работает. Сделав что-то не то, нельзя тут же откатиться назад, что поначалу пугает. При этом конечный результат в визуальном редакторе по-прежнему может отличаться от того, что ты увидишь в запущенном приложении.

Рис. 3. Организация рабочего пространства в Design
Рис. 3. Организация рабочего пространства в Design

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

 

Outro

Упрощение интерфейсов — логичный тренд, который работает не только в IT. Уже давно редактор Vim перестал быть № 1 среди линуксоидов, вот и редактор XML скоро будет не для всех. Но в предложенных инструментах еще много минусов, которые неприемлемы при решении серьезных задач. Время покажет, станет ли ConstraintLayout макетом по умолчанию или же тихо забудется, как Google Glass.

Оставить мнение