AIMP for Android v2.50 — Темы

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

В первую очередь, хочу заметить, что тема — это частный случай скина, сильно урезанный по возможностям. В нашем случае, тема позволяет изменить внешний вид элементов и их положение в пределах окна, так же вы можете безболезненно создавать и удалять элементы, что не имеют имени — атрибута name.

В качестве примера я взял скин Pandemic из первой версии плеера. Давайте перенесем его на v2.50.

Структура скина

Скачиваем оригинальный скин Bliss_Dark, и открываем его как zip-архив в любом удобном вам архиваторе. Вот что мы видим внутри:

Structure of theme

На верхнем уровне расположены:

  • skin.png — карта текстур, в ней расположены абсолютно все текстуры, что используются в теме
  • skin.xml — содержит информацию о скине, а так же коллекцию общих цветов.

Следующий уровень — папка Views. В ней содержатся XML-файлы с описанием макета каждого конкретного экрана, вкладки, элементов и т.п. Обратите внимание на подпапки — phone, tablet, а так же подпапки внутри них. Как вы, наверное, догадались: эти папки содержат макеты для определенных типов устройств и ориентации экрана.
Как это работает? Рассмотрим пример: планшет в ландшафтном режиме, при загрузке экрана движок плеера сначала попробует загрузить нужный XML-файл из папки Views/Tablet/Landscape, если его там нет — загрузит из корня — из папки Views.

  • common.playlist.xml — макет экрана с плейлистом
  • common.playlist.group.xml — макет группы внутри плейлиста в обычном режиме
  • common.playlist.group.delete.xml — макет группы внутри плейлиста в режиме удаления
  • common.playlist.group.sort.xml — макет группы внутри плейлиста в режиме сортировки
  • common.playlist.item.xml — макет строки внутри плейлиста в обычном режиме
  • common.playlist.item.delete.xml — макет строки внутри плейлиста в режиме удаления
  • common.playlist.item.sort.xml — макет строки внутри плейлиста в режиме сортировки
  • dspmanager.xml — макет окна менеджера звуковых эффектов
  • dspmanager.basic.xml — макет вкладки «общее»
  • dspmanager.equalizer.xml — макет вкладки «эквалайзер»
  • filedialog.files.xml — макет окна добавления файлов
  • filedialog.files.item.xml — макет строки списка файлов
  • filedialog.files.item.checked.xml  — макет строки списка файлов с возможность отметить ее галочкой
  • filedialog.save.xml — макет окна сохранения файлов
  • fileinfo.xml — макет окна «информация о файле»
  • fileinfo.basic.xml — макет вкладки «общая информация о файле»
  • fileinfo.lyrics.xml — макет вкладки «стихи»
  • main.xml — макет главного окна программы
  • main.player.xml — макет главного экрана программы
  • navigator.xml — макет навигационного меню, что появляется с левой стороны экрана
  • navigator.command.xml — макет строки с командой
  • navigator.separator.xml — макет разделителя
  • navigator.tab.xml — макет строки с вкладкой плейлиста
  • navigator.tab.new.xml — макет строки с кнопкой «добавить новую вкладку»
  • sleeptimer.xml — макет окна таймера сна

Макет главного окна

Макет главного окно определяется файлом main.xml и поддерживает разбиение на несколько экранов:

<mainView row_count="1">
   <view name="main.player"/>
   <view name="common.playlist" />
</mainView>

Атрибут row_count определяет количество строк, экраны располагаются по строкам равномерно.

Как здесь мы видим, макет главного окна ссылается на два других макета — на макеты экрана плеера и плейлиста. В свою очередь, если открыть main.xml из views\tablet\portrait, что предназначен для планшета, мы увидим ссылку только на один макет:

<mainView row_count="1">
   <view name="main.player"/>
</mainView>

На самом деле здесь все просто — для планшетного вида содержимое common.playlist.xml помещено в макет main.player.xml, но элементы плейлиста по-прежнему остались в пределах окна плейлиста. Этот момент очень важен. Если именованные элементы будут перенесены в другое окно — программа просто «упадет» во время загрузки скина.

Карта текстур

Для того, чтобы не переписывать координаты текстур у всех элементов в теме, я заменил исходные текстуры текстурами из Pandemic-a. Моя карта стала выглядеть так:

Texture Map

Знакомые цвета, не правда ли?

Обратите внимание на области, залитые черным цветом — это специально помеченные области, на которые никто не ссылается в XML-файлах. Здесь вы можете безболезненно размещать свои собственные текстуры, если понадобится. Хочу заметить, что вы так же можете изменить размер карты, если существующих областей вам не будет хватать.

Для реализации Pandemic-а я добавил две новых текстуры — для дисплея с обложкой альбома (координаты: 356 858 404 906) и для фона заголовка окна (координаты: 0 482 18 567).

Макет экрана плеера

Итак, карта текстур обновлена, остается дело за малым — поправить отступы и цвета у некоторых элементов в макетах. Я рассмотрю процесс редактирования только главного экрана плеера.

Итак, поехали, открываем main.player.xml:

<com.aimp.skinengine.controls.SkinnedContainer 
    background_color="255 64 64 64"
>
    <com.aimp.skinengine.controls.SkinnedContainer
        background_color="255 48 48 48"
        placement_anchors="1 1 1 0"
        placement_size="0 80"
    >
        <com.aimp.skinengine.controls.SkinnedButton 
          skin0="483 760 563 840"
          skin1="564 760 644 840"
          placement_anchors="1 1 0 0"
          placement_size="80 80" 
          name="btnShowNavigator"
        /> 

        <com.aimp.skinengine.controls.SkinnedLabel 
          text_color="255 255 255 255"
          text_size="24"
          placement_anchors="1 1 1 0"
          placement_margins="88 8 70 0" 
          placement_size="0 40" 
          name="tcSongName"
        /> 
 
        <com.aimp.skinengine.controls.SkinnedLabel 
          text_color="255 150 150 150"
          text_size="20"
          placement_anchors="1 1 1 0"
          placement_margins="88 36 70 0" 
          placement_size="0 40" 
          name="tcSongInfo"
        /> 

        <com.aimp.skinengine.controls.SkinnedButton
          skin0="483 679 563 759"
          skin1="564 679 644 759"
          placement_anchors="0 1 1 0"
          placement_size="80 80" 
          name="btnMenu"
        /> 
 
     </com.aimp.skinengine.controls.SkinnedContainer>
 
     <com.aimp.skinengine.controls.SkinnedControl
        skin0="00 777 080 857"
        skin1="81 777 161 857"
        placement_anchors="1 1 0 0"
        placement_margins="20 80 0 0"
        placement_size="80 80" 
        name="btnShuffle" 
     />

     <com.aimp.skinengine.controls.SkinnedLabel
        text_color="255 120 120 120"
        text_size="22"
        text_align="1"
        placement_margins="110 100 110 0" 
        placement_anchors="1 1 1 0"
        placement_size="200 40" 
        name="tcQueueInfo"
     /> 
 
    <com.aimp.skinengine.controls.SkinnedControl
        skin0="162 777 242 857"
        skin1="243 777 323 857"
        skin2="324 777 404 857"
        placement_anchors="0 1 1 0"
        placement_margins="0 80 20 0"
        placement_size="80 80" 
        name="btnRepeat" 
    />
 
    <com.aimp.skinengine.controls.SkinnedImageDisplay 
        background_color="255 75 75 75"
        placement_anchors="1 1 1 1"
        placement_margins="0 160 0 190" 
        keepSquareAspectRatio="false"
        name="ivCAD"
    /> 
 
    <com.aimp.skinengine.controls.SkinnedSlider
        skin="416 194 422 232"
        skin_sizing_margins="0 16 0 16"
        skin_progress="377 194 383 232"
        skin_progress_sizing_margins="0 16 0 16"
        skin_thumb="322 194 360 232"
        placement_anchors="1 0 1 1"
        placement_margins="40 0 40 140"
        placement_size="0 40"
        name="sbSeekBar"
    /> 
 
    <com.aimp.skinengine.controls.SkinnedLabel 
        text_color="255 120 120 120"
        text_size="20"
        placement_anchors="1 0 0 1"
        placement_margins="40 0 0 110" 
        placement_size="100 30" 
        name="tcTrackPosition"
    /> 
 
    <com.aimp.skinengine.controls.SkinnedLabel 
        text_color="255 120 120 120"
        text_size="20"
        text_align="2"
        placement_anchors="0 0 1 1"
        placement_margins="0 0 40 110" 
        placement_size="100 30" 
        name="tcTrackDuration"
    />
 
    <com.aimp.skinengine.controls.SkinnedContainer
        background_color="255 48 48 48"
        placement_anchors="1 0 1 1"
        placement_size="0 96"
    >
 
         <com.aimp.skinengine.controls.SkinnedButton
             skin0="322 0 482 96"
             skin1="322 97 482 193"
             placement_anchors="1 0 0 1"
             placement_size="160 96"
             name="btnPrev"
         /> 

         <com.aimp.skinengine.controls.SkinnedButton
             skin0="161 0 321 96"
             skin1="161 97 321 193"
             placement_anchors="0 0 0 1"
             placement_size="160 96"
             name="btnPause"
         /> 
 
         <com.aimp.skinengine.controls.SkinnedButton
             skin0="0 0 160 96"
             skin1="0 97 160 193"
             placement_anchors="0 0 0 1"
             placement_size="160 96"
             name="btnPlay"
         /> 

         <com.aimp.skinengine.controls.SkinnedButton
             skin0="0 194 160 290"
             skin1="161 194 321 290"
             placement_anchors="0 0 1 1"
             placement_size="160 96"
             name="btnNext"
         /> 

     </com.aimp.skinengine.controls.SkinnedContainer>

</com.aimp.skinengine.controls.SkinnedContainer>

В главном экране почти все готово — осталось поправить внешний вид верхней и нижней панелей, текстуру и положение элемента, что отвечает за показ обложки альбома.

Верхняя панель здесь представлена вторым элементом типа SkinnedContainer:

    <com.aimp.skinengine.controls.SkinnedContainer
        background_color="255 48 48 48"
        placement_anchors="1 1 1 0"
        placement_size="0 80"
    >

Нас интересует атрибут background_color — как вы видите, в Bliss панель рисуется просто цветом, в Pandemic-е — текстурой с тенью снизу, которую мы добавили выше в нашу карту. Вместо цвета указываем ссылку на карту текстур и задаем параметры растягивания:

 <com.aimp.skinengine.controls.SkinnedContainer
     skin="0 482 18 567"
     skin_sizing_margin="0 0 0 10"
     placement_anchors="1 1 1 0"
     placement_size="0 80"
 >

Для тех, кто знаком с редактором скинов для ПК версии, будет не сложно разобраться со свойствами и параметрами элементов — в мобильной версии все практически то же самое, только без высокоуровневой автоматизации. Ниже я представлю список всех возможных типов элементов и их свойств с кратким описанием.

Аналогичным образом поступаем с нижней панелью (последний элемент с типом SkinnedContainer в списке) — но вместо указания текстуры меняем цвет с темно-серого на оранжевый:

 <com.aimp.skinengine.controls.SkinnedContainer
     background_color="255 246 141 16"
     placement_anchors="1 0 1 1"
     placement_size="0 96"
 >

Остался элемент, отображающий обложки альбомов. Находим его в файле по имени ivCAD. Так же, как и у верхней панели, задаем ему текстуру и параметры растягивания:

    <com.aimp.skinengine.controls.SkinnedImageDisplay 
        skin="356 858 404 906" 
        skin_sizing_margins="10 10 10 10"
        placement_anchors="1 1 1 1"
        placement_margins="30 160 30 190" 
        keepSquareAspectRatio="true"
        image_padding="9 9 9 9"
        name="ivCAD"
    />

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

Аналогичным образом я прошел макеты всех остальных окон и обновил их под стиль старого Pandemic-а. Как и оригинальные обложки Bliss, Pandemic можно скачать здесь.

Описание свойств элементов

Общие свойства

  • name — имя элемента, только для чтения.
  • placement_anchors — значение якорей в формате «left top right bottom», каждое из значений может принимать 0 или 1*
  • placement_margins — отступ от соответствующего края предка в формате «left top right bottom» *
  • placement_margins_is_in_percents — указывает, что отступы для соответствующей стороны заданы в %, задаются в формате «left top right bottom», каждое из значений может принимать 0 или 1*
  • placement_size — размеры элемента в формате «width height»*

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

SkinnedControl

  • skinX — координаты текстуры в карте skin.png, задаются в формате «left top right bottom»
  • skinX_sizing_margins — отступы от краев при растяжении текстуры, задаются в формате «left top right bottom»
  • background_colorX — цвет фона для состояния X, используется только в том случае, если для этого состояния отсутствует свойство skinX. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255

X — номер состояния, может принимать значения от 0 до 9

SkinnedContainer и SkinnedScrollView

Может содержать в себе другие элементы

  • skin — координаты текстуры в карте skin.png, задаются в формате «left top right bottom»
  • skin_sizing_margins — отступы от краев при растяжении текстуры, задаются в формате «left top right bottom»
  • background_color — цвет фона, используется только в том случае, если отсутствует свойство skin. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255

SkinnedLabel

Текстовая метка, наследуется от SkinnedControl

  • text_color — цвет текста, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • text_color_disabled — цвет текста для недоступного состояния элемента, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • text_size — размер шрифта
  • text_align — выравнивание текста внутри элемента, 0 — по левому краю, 1 — по центру, 2 — по правому краю
  • text_padding — отступы от краев элемента, где будет позиционироваться текст, задаются в формате «left top right bottom»
  • wordwrap — указывает, поддерживает ли элемент перенос текста на новую строку по словам, возможные значения: 0 / 1
  • text — отображаемый текст, не поддерживает локализацию, может отсутствовать

SkinnedButton

Кнопка, наследуется от SkinnedLabel. Поддерживает два состояния для фона: 0 — обычное, 1 — нажатое.

  • Glyph — координаты текстуры в карте skin.png, задаются в формате «left top right bottom»

SkinnedListView и SkinnedDragSortListView

  • skin — координаты текстуры в карте skin.png, задаются в формате «left top right bottom»
  • skin_sizing_margins — отступы от краев при растяжении текстуры, задаются в формате «left top right bottom»
  • background_color — цвет фона, используется только в том случае, если отсутствует свойство skin. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255

SkinnedProgress

  • skin — координаты текстуры фона в карте skin.png, задаются в формате «left top right bottom»
  • skin_sizing_margins — отступы от краев при растяжении текстуры фона, задаются в формате «left top right bottom»
  • background_color — цвет фона, используется только в том случае, если отсутствует свойство skin. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • skin_progress — координаты текстуры прогресса в карте skin.png, задаются в формате «left top right bottom»
  • skin_progress_sizing_margins — отступы от краев при растяжении текстуры прогресса, задаются в формате «left top right bottom»
  • progress_color — цвет фона, используется только в том случае, если отсутствует свойство skin_progress. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • vertical — ориентация полосы прогресса, 0 — горизонтальная, 1 — вертикальная

SkinnedRichView

Текстовое поле для отображения многострочного текста с поддержкой форматирования

  • text_color — цвет текста, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • text_size — размер шрифта

SkinnedSlider

Наследуется от SkinnedProgress

  • skin_thumb — координаты текстуры для ползунка в карте skin.png, задаются в формате «left top right bottom»
  • skin_thumb_sizing_margins — отступы от краев текстуры при ее растяжении, задаются в формате «left top right bottom»

SkinnedImageDisplay

  • skin — координаты текстуры фона в карте skin.png, задаются в формате «left top right bottom»
  • skin_sizing_margins — отступы от краев при растяжении текстуры фона, задаются в формате «left top right bottom»
  • background_color — цвет фона, используется только в том случае, если отсутствует свойство skin. Задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • image_padding — отступы от границ фоновой текстуры, задают область, где будет рисоваться изображение. Задаются в формате «left top right bottom»
  • KeepSquareAspectRatio — принимает значения 0 или 1. В случае 1 — элемент управления подгоняет свой размер в пределах установленной позиции так, чтобы содержимое всегда было квадратным

SkinnedPlaylistItem

  • line1_text_color — цвет текста для первой строки, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • line1_text_size — размер шрифта
  • line2_text_color — цвет текста для второй строки, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • line2_text_size — размер шрифта
  • time1_text_color — цвет текста для области отображения времени в первой строке, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • time1_text_size — размер шрифта
  • time2_text_color — цвет текста для области отображения времени во второй строке, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • time2_text_size — размер шрифта
  • queue_text_color — цвет текста для области с номером трека в пользовательской очереди воспроизведения, отображается в первой строке, задается в формате «Alpha Red Green Blue», каждая из компонент может принимать значения от 0 до 255
  • queue_text_size — размер шрифта
  • queue_area_size — максимальный размер области с номером трека в пользовательской очереди воспроизведения
  • time_area_size — размер областей для отображения времени в первой и второй строках

AIMP for Android v2.50 — Темы: 4 комментария

  1. Ya-Grisha

    «time2_text_color — цвет текста для области отображения времени во второй строке,»
    Артём, хоть убей меня! Не могу понять, откуда взять второе время? Поясни, в каких случаях оно отображается? У меня во второй строке никогда время не отображалось.

  2. Ya-Grisha

    Артём, добавь в статью новые параметры.
    Новыми параметрами в Skin.xml:

    Для Views XML-ок:
    Для «lvFileDlgListView» и «lvPlaylist» можно задать дополнительный локальный акцент: accent_color=»255 Х Х Х»
    Для edPlaylistName: selection_color=»255 Х Х Х»

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