Недавно стартовало публичное бета-тестирование новой версии AIMP для Android, я хотел бы разобрать вопрос создания собственных тем для плеера, поскольку редактора тем для мобильного AIMP еще в глубокой разработке – собирать тему придется вручную. Итак.
В первую очередь, хочу заметить, что тема – это частный случай скина, сильно урезанный по возможностям. В нашем случае, тема позволяет изменить внешний вид элементов и их положение в пределах окна, так же вы можете безболезненно создавать и удалять элементы, что не имеют имени – атрибута name.
В качестве примера я взял скин Pandemic из первой версии плеера. Давайте перенесем его на v2.50.
Структура скина
Скачиваем оригинальный скин Bliss_Dark, и открываем его как zip-архив в любом удобном вам архиваторе. Вот что мы видим внутри:
На верхнем уровне расположены:
- 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. Моя карта стала выглядеть так:
Обратите внимание на области, залитые черным цветом – это специально помеченные области, на которые никто не ссылается в 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 – размер областей для отображения времени в первой и второй строках
«time2_text_color — цвет текста для области отображения времени во второй строке,»
Артём, хоть убей меня! Не могу понять, откуда взять второе время? Поясни, в каких случаях оно отображается? У меня во второй строке никогда время не отображалось.
Используется в диалоге закладок
О! Точно! Благодарю.
Артём, добавь в статью новые параметры.
Новыми параметрами в Skin.xml:
Для Views XML-ок:
Для “lvFileDlgListView” и “lvPlaylist” можно задать дополнительный локальный акцент: accent_color=”255 Х Х Х”
Для edPlaylistName: selection_color=”255 Х Х Х”
почему в шторке и на экране блокировки перестали работать темы? теперь они всегда светлые.
А они, разве, там когда-либо работали?
предыдущая версия программы
https://drive.google.com/file/d/0Bz2K0xtlFOFkMEdSVzN3c2k0dlk/view?usp=drivesdk
новая версия
https://drive.google.com/file/d/0Bz2K0xtlFOFkOEhzWGRNMHFLU1U/view?usp=drivesdk
Я знаю, виджет изменился. Только что тогда, что сейчас – его вид был жестко задан на стороне программы и не зависел ни от темы ОС, ни от темы плеера, и настроить его было нельзя. Собственно, в новом виджете лишь панель управления поменяла свой цвет – стала белой.
У меня вопрос. Могут ли в дальнейшем в AIMP реализованы 32- и 64-битные архитектуры как в альфа-версии PowerAMP3 ?
Какие именно архитектуры? х86 уже есть. Нужна х86-64 или ARM64?
Я имею ввиду новый аудио-движок, 32 и 64 бита именно под ОС Андроид, я об этом.
У нас он изначально 32-битный. А 64-бита нет даже в версии для ПК – это излишняя роскошь.