Android: повернуть картинку через XML

Иногда в Android-проекте требуется иметь несколько версий одной и той же картинки, но с поворотом на определённый угол. Скажем, речь может идти об указывающих на что-то стрелках, «хвостиках» контекстных balloon-ов, градиентных границах и тому подобной графике.

Конечно, требования к некоторым картинкам бывают таковы, что дизайнеру приходится вращать их вручную, дорисовывая недостающие детали. Но если кроме угла поворота никаких отличий нет, то плодить много графических ресурсов попросту неразумно: растёт размер .apk, усложняется внесение изменений, да ещё и нарушается принцип «работать должна машина»… в общем, неудивительно что подобные сценарии учтены в Android с самых первых версий, и мы можем со спокойной совестью пользоваться уже готовым инструментом. Например, на скриншоте ниже использовано только одно растровое изображение оранжевой стрелочки — то, что в заголовке. Остальные варианты получены через xml drawables, без единой строчки java-кода!

Поворот одной и той же картинки на разные углы
Поворот одной и той же картинки на разные углы

Эта магия становится возможной благодаря RotateDrawable, вернее — XML-представлению такого типа Drawable через тег <rotate>. Размещаются такие ресурсы в каталоге drawable (разумеется, без всяких -dpi), и для поворота изображения на 180° файл будет выглядеть, например, так:

Где, соответственно:

  • drawable — ссылка на поворачиваемую картинку; в примере это ic_launcher.png
  • fromDegrees — начальный угол поворота, в градусах
  • toDegrees — конечный угол поворота, тоже в градусах
  • pivotX — опорная точка по X
  • pivotY — опорная точка по Y

То есть изображение drawable поворачивается на угол от fromDegrees до toDegrees вокруг некой оси, заданной координатами [pivotX, pivotY]. В нашем случае начальный и конечный углы поворота совпадают, а опорная точка выбрана ровно посередине картинки — 50% по X и по Y. Для ясности — можно представить pivotX и pivotY как координаты булавки, которой мы «прикалываем» изображение и вокруг которой его потом крутим.

Поворот вокруг виртуальной «булавки»
Поворот вокруг виртуальной «булавки»

Скажем, в написанном мной когда-то приложении QIP Speed Test такая «булавка» виртуально воткнута в центр круглого основания стрелки спидометра:

Опорная точка — в основании стрелки «спидометра»
Опорная точка — в основании стрелки «спидометра»

Для большинства случаев подойдёт вращение именно вокруг центра, те самые 50%. Но если с опорной точкой всё достаточно ясно и наглядно, то почему же всё-таки угол поворота задаётся диапазоном значений, from и to?

Это ещё одна полезнейшая заготовка из арсенала Android — поворот может вычисляться между заданными границами пропорционально «уровню» Drawable, установленному через setLevel(). Но это уже совсем другая история; сейчас же нас интересует неизменность повёрнутой картинки при любом состоянии, а потому просто зададим оба этих значения равными нужному углу.

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

Пусть работает всё-таки машина, а не человек.

Android: повернуть картинку через XML
5, голосов: 2


Комментарии:

2 комментария на «“Android: повернуть картинку через XML”»

  1. […] Именно здесь и кроется причина поиска drawer-а по его gravity, а не по его позиции. Чтоб получить вторую выезжающую панель, следует всего лишь добавить второй дочерний элемент в DrawerLayout и установить его layout_gravity как end. И, в принципе, дополнительной настройки для правого drawer-а уже не нужно — разве только установить для него подходящую тень, полученную при помощи поворота имеющейся картинки на 180° (не вручную, конечно, а средствами системы, подробнее здесь: Android: повернуть картинку через XML). […]

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Капча (решите пример) *