Если вы хотите использовать PNG- или JPEG-изображения в своём приложении, вы должны будете предоставить несколько копий этих изображений для разных плотностей экрана. При большом количестве таких изображений это может сделать ваше приложение весьма громоздким. Решение здесь – использовать вместо картинок изображения, описанные с помощью XML.
Фактически, XML Drawable это серия команд, которая описывает, как нарисовать изображение на экране. Поэтому они могут изменяться под любую плотность экрана без какой-либо потери качества. Мы можем манипулировать ими даже когда приложение работает.
Недостатком такого подхода может являться то, что такие изображения можно использовать только там, где используются обычные Drawable. Другой проблемой может являться то, что их рисование иногда занимает больше времени, чем рисование растрового изображения. Однако эти минусы не так существенны перед возможностями модифицировать изображения и уменьшить размер APK приложения. В этой статье мы разберём несколько примеров реализации XML Drawable в приложении.
Основные элементы
При рисовании изображения в XML главным тегом является <shape> – корневой элемент для геометрической фигуры. Он имеет следующие атрибуты:
- android:shape – тип фигуры. Может принимать значения oval, rectangle, ring, line. Если атрибут не задан, то по умолчанию берётся rectangle.
- android:innerRadius – радиус внутренней части кольца. Используется для ring.
- android:innerRadiusRatio – радиус внутренней части кольца, выраженный как отношение ширины кольца. Используется для ring.
- android:thickness – толщина кольца. Используется для ring.
- android:thicknessRatio – толщина кольца, выраженная как отношение ширины кольца. Используется для ring.
- android:useLevel – true если используется как LevelListDrawable. Обычно должен быть false, иначе ваша фигура может не отобразиться.
Затем внутри тега <shape> используются следующие теги:
- <corners> – создаёт закруглённые углы для фигуры. Применяется только тогда, когда в атрибуте android:shape задано значение rectangle. Атрибуты:
- android:radius – радиус закругления углов. В данном случае все углы будут иметь одинаковый радиус, однако вы можете переопределить радиус отдельно для каждого угла с помощью атрибутов ниже.
- android:topLeftRadius – верхний левый угол.
- android:topRightRadius – верхний правый угол.
- android:bottomLeftRadius – нижний левый угол.
- android:bottomRightRadius – нижний правый угол.
- <gradient> – задаёт параметры градиента для фигуры. Атрибуты:
- android:angle – угол для градиента, в градусах. Должен быть кратным 45.
- android:centerX – смещение X-координаты относительно центра градиента.
- android:centerY – смещение Y-координаты относительно центра градиента.
- android:startColor – начальный цвет градиента.
- android:centerColor – дополнительный цвет, который находится между начальным и конечным цветами.
- android:endColor – конечный цвет градиента.
- android:gradientRadius – радиус градиента. Применяется только при типе градиента radial,
- android:useLevel – true, если используется как LevelListDrawable.
- android:type – тип градиента. Может иметь следующие значения: linear – линейный градиент (по умолчанию); radial – радиальный, начальный цвет находится в центре; sweep – развёрточный градиент, который идёт по кругу вокруг центра.
- <solid> – заполняет фигуру сплошным цветом. Атрибуты:
- android:color – цвет заливки.
- <stroke> – рисует линию для фигуры. Можно рассматривать как границу фигуры. Атрибуты:
- android:width – толщина линии.
- android:color – цвет линии.
- android:dashWidth – толщина каждого штриха. Работает только в случае, если задан атрибут android:dashGap.
- android:dashGap – расстояние между штрихами. Работает только в случае, если задан атрибут android:dashWidth.
- <size> – задаёт размер фигуры. Атрибуты:
- android:width – ширина фигуры.
- android:height – высота фигуры.
- <padding> – отступы, применяемые к содержимому элемента View. Меняет отступы только View, не самой фигуры. Атрибуты:
- android:left – отступ слева.
- android:right – отступ справа.
- android:top – отступ сверху.
- android:bottom – отступ снизу.
Теперь, когда мы знаем, из каких элементов составляются изображения, посмотрим несколько примеров того, как можно.
Круг с градиентом
Вы можете использовать XML Drawables для создания элементов дизайна или функциональных элементов интерфейса. Например, можно нарисовать вот такой круг и залить его градиентом.
В результате получим вот такое изображение.
Фон для кнопки
Кнопкам в Android можно задавать различный фон, в том числе и собственноручно нарисованный. Это довольно просто и не требует особо большого количества элементов. Например, кнопку ниже можно использовать для навигации в приложении.
Фон для текста
Аналогично кнопка, TextView также можно задать любой фон. Например, вот так:
Или так:
Использование Layer List
Бывают ситуации, когда нужно составить изображение из разных фигур. Это возможно с помощью тега <layer-list>, который позволяет комбинировать элементы <shape>. Каждый элемент внутри <layer-list> рисуется в порядке списка – последний в списке рисуется поверх остальных слоёв. Каждая фигура <shape> помещает в тег <item>, который представляет собой элемент списка.
Например, можно создать вот такую комбинацию из двух эллипсов, которую можно использовать как метку для маркированного списка.
А с помощью кода ниже можно создать подобие почтовой марки:
Использовать фигуры одного типа необязательно, можно использовать разные типы. Нарисуем иконку, комбинирующую прямоугольник и линию, перечёркивающую его.
StateDrawable
У некоторых элементов интерфейса существуют различные состояния, с которыми можно работать. Например, у Button можно отслеживать состояние pressed (нажат) и менять при этом фон кнопки. Для этого создадим селектор, который будет отслеживать состояния кнопки и ставить нужный фон.
У селектора есть следующие атрибуты, определяющие состояние элемента:
- android:state_pressed – когда пользователь нажимает на элемент.
- android:state_focused – когда на элементе установлен фокус ввода.
- android:state_enabled – когда элемент доступен.
- android:state_checked – когда элемент в списке был отмечен.
С помощью значений true\false определяем, какое состояние нужно отследить и в атрибут android:drawable добавляем нужный фон.
button_pressed.xml:
button_focused.xml:
button_enabled.xml:
В результате получим следующую кнопку, которая будет менять свой цвет в зависимости от состояния.
Кнопки это не единственные элементы, у которых можно отслеживать состояния. Например, это можно делать также для элементов RadioButton и CheckBox с помощью атрибута android:state_checked. Например, с помощью кода ниже можно добавить в приложение свою картинку, которой будет отмечаться выбранный элемент CheckBox.
Аналогичным образом отслеживается состояние у RadioButton.
В качестве drawable здесь может быть любое изображение, в нашем приложении “Карточки для детей” с помощью селекторов используются белые галочки и фон.
Также в селекторе вместо изображений можно рисовать свои собственные фигуры, как это показано ниже.
Здесь мы при нажатии на кнопку делаем её чуть темнее.
Как можно увидеть, у XML Drawables есть множество применений, которое ограничивается лишь фантазией разработчика. Рисование своих изображений поможет сделать ваше приложение уникальнее и заметнее среди других.
Спасибо за познавательную статью!
А есть ли способ добавить тень контролу в api V17 – 19 ?
Спасибо.