Предоставление ресурсов для приложения Android Печать
Добавил(а) microsin   

Перевод документации [1], в которой рассказывается о размещении различных ресурсов в программе Android. Все незнакомые сокращения и термины ищите в Словарике [5].

Вы всегда должны содержать ресурсы приложения (такие как изображения и строки) отдельно от Вашего кода - чтобы ресурсы можно было поддерживать независимо. Вы также должны предоставить альтернативные ресурсы для специальных конфигураций устройств Android, группируя их с помощью специальным образом именованных директорий ресурсов. Во время выполнения Android использует подходящие ресурсы, основываясь на текущей конфигурации. Например, Вы можете захотеть предоставить различную планировку интерфейса пользователя (UI layout) в зависимости от размера экрана или различные строки в зависимости от установок языка.

Как только Вы разместили ресурсы Вашего приложения, Вы можете получить к ним доступ с использованием идентификаторов ресурса (resource ID), которые автоматически генерируются в классе R проекта. Как использовать ресурсы в программе, рассказывается в [3]. Этот документ показывает, как группировать Ваши ресурсы в проекте Android, и предоставить альтернативные ресурсы для специфических конфигураций устройств.

[Группировка ресурсов по их типам]

Вы должны разместить каждый тип ресурса в отдельной поддиректории в директории res/ Вашего проекта. Например, вот такая конфигурация может быть для простого проекта:

MyProject/
    src/  
        MyActivity.java  
    res/
        drawable/  
            icon.png  
        layout/  
            main.xml
            info.xml
        values/  
            strings.xml

Как Вы можете увидеть увидеть в этом примере, каталог res/ содержит все ресурсы (распределенные по поддиректориям): ресурс картинки, два ресурса layout, и файл строковых ресурсов. Имена директорий ресурсов имеют особое значение, и эти имена перечислены в таблице 1.

Таблица 1. Подкаталоги ресурсов, находящихся в директории res/ проекта.

ДиректорияТип ресурса (Resource Type)
animator/ Файлы XML, которые определяют анимации свойств объектов (property animations).
anim/ Файлы XML, которые определяют tween animations (что это такое, см. [2]). В эту директорию могут быть также сохранены анимации свойств (property animations), однако для анимаций свойств предпочтительнее директория animator/, чтобы отличать эти два типа.
color/ Файлы XML, которые задают список цветов [2].
drawable/

Файлы растровых изображений (bitmap в форматах .png, .9.png, .jpg, .gif) или файлы XML, которые компилируются в следующие подтипы drawable-ресурсов:

  • Файлы Bitmap
  • Nine-Patches (файлы bitmap с изменяемыми размерами)
  • State lists (списки состояний)
  • Shapes (фигуры)
  • Animation drawables (анимированные рисуемые объекты)
  • Другие рисуемые (drawable) объекты
layout/ Файлы XML, которые определяют внешний вид интерфейса пользователя (interface layout), см. Layout Resource.
menu/ Файлы XML, которые определяют меню приложения, такие как Options Menu (меню опций), Context Menu (контекстное меню) или Sub Menu (дочернее меню). См. Menu Resource.
raw/

Произвольные файлы для сохранения их в том виде, как есть (raw, "сырые" ресурсы). Чтобы открыть эти ресурсы через сырой поток InputStream, вызовите Resources.openRawResource() с идентификатором ресурса (resource ID), который указывается как R.raw.filename.

Однако, если Вам нужно получить доступ к оригинальным именам файлов и файловой иерархии, Вы можете принять решение сохранить некоторые ресурсы в папке assets/ (вместо res/raw/). Файлы в assets/ не имеют resource ID, так что Вы их можете читать напрямую только с использованием AssetManager.

values/

Файлы XML, которые содержат простые значения, такие как строки, целые числа, цвета.

Принимая во внимание, что файлы ресурсов XML в других поддиректориях res/ определяют единственный ресурс на основе имени файла XML, файлы в директории values/ описывают несколько ресурсов сразу. Для файла в этой директории каждый дочерний элемент задает один ресурс. Например, элемент создает ресурс R.string и элемент создает ресурс R.color.

Потому что каждый ресурс задает свой собственный элемент (тег) XML, Вы можете выбрать имя файла как хотите, и разместить различные ресурсы в одном файле. Однако для ясности Вы можете захотеть разместить уникальные типы ресурсов в разных файлах. Например, здесь предлагается система именования для файлов, которые Вы можете сохранить в этой директории:

См. String Resources, Style Resource и More Resource Types.

xml/ Произвольные файлы XML, которые могут быть прочитаны во время выполнения программы (runtime) путем вызова Resources.getXML(). Здесь должны быть сохранены различные конфигурационные файлы XML, такие как искомая конфигурация (searchable configuration).

Внимание: никогда не сохраняйте файлы ресурсов напрямую в директории res/ (без разделения по её дочерним директориям) - это приведет к ошибке компиляции. Не используйте для имен файлов ресурсов заглавных, русских букв, пробелов и спецсимволов - это также приведет к ошибке. Кроме того, имена файлов ресурсов всегда должны начинаться с буквы.

Для дополнительной информации по основным типам ресурсов см. [2].

Ресурсы, которые Вы сохраняете в подкаталогах, определенных в таблице 1, являются Вашими ресурсами "по умолчанию" (default resources). Т. е. эти ресурсы определяют оформление внешнего вида по умолчанию для приложения и его содержание. Однако различные типы устройств на базе OS Android могут применять разные типы ресурсов. Например, если устройство имеет экран, который больше обычного, то Вы должны предоставить различные layout-ресурсы, чтобы правильно задействовать дополнительное пространство на экране. Или, если устройство имеет другой установленный язык, то Вы должны предоставить отдельные строковые ресурсы, чтобы перевести на этот язык текст, отображаемый в интерфейсе. Для предоставления этих различных ресурсов для различных конфигураций устройств Вам нужно предоставить альтернативные ресурсы в дополнение к ресурсам по умолчанию.

[Предоставление альтернативных ресурсов]

Почти каждое приложение должно предоставить альтернативные ресурсы для поддержки специфических конфигураций устройств. Например, Вы должны подключить альтернативные рисуемые ресурсы (drawable resources) для различных плотностей точек экрана и альтернативные строковые ресурсы для разных языков. Во время выполнения Android автоматически определит текущую конфигурацию устройства и загрузит в приложение подходящие ресурсы.

Android-Providing-Resources-goals-fig1

Рис. 1. Два различных устройства, каждое использует разные layout-ресурсы.

Чтобы определить зависящий от конфигурации альтернативный набор ресурсов нужно сделать следующее:

1. Создайте новую директорию в папке res/, которая будет именоваться по шаблону < resources_name >-< config_qualifier >.

< resources_name > является именем директории соответствующего ресурса по умолчанию (это одно из имен в таблице 1).
< qualifier > это имя, которое указывает отдельную конфигурацию, для которой будут использоваться эти ресурсы (одно из имен в таблице 2).

Вы можете добавить больше чем один < qualifier >. Отделяйте каждый друг от друга через дефис.

Внимание: когда добавляете несколько квалификаторов, Вы должны их разместить в том же порядке, в каком они перечислены в таблице 2. Если квалификаторы будут размещены в неправильном порядке, то ресурсы будут игнорироваться.

2. Сохраните соответствующие альтернативные ресурсы в этой новой директории. Файлы ресурсов должны быть поименованы абсолютно так же, как и файлы ресурсов по умолчанию.

Например, имеется ресурсы по умолчанию и альтернативные:

res/
    drawable/   
        icon.png
        background.png    
    drawable-hdpi/  
        icon.png
        background.png

Квалификатор hdpi показывает, что ресурсы в этой директории предназначены для устройств с экранами высокой плотности (high-density). Картинки в каждой из этих drawable-директорий имеют размер для своей специфической плотности экрана, но имена файлов полностью одинаковые. При таком методе доступа resource ID, которые Вы используете для ссылки на icon.png или background.png, останутся всегда одинаковыми для разных конфигураций, однако Android выберет версию каждого ресурса, которая лучше подходит для текущего устройства путем сравнения информации конфигурации устройства с квалификаторами в имени директории ресурсов.

Android поддерживает несколько квалификаторов конфигурации, и Вы можете добавить несколько квалификаторов в имя одной директории, но отделить каждое устройство черточкой в имени. В таблице 2 перечислены допустимые квалификаторы конфигурации в порядке приоритета — если Вы используете несколько квалификаторов для одной директории ресурса, то Вы должны добавить эти квалификаторы в имя директории в том же порядке, как они перечислены в таблице 2.

Таблица 2. Имена квалификаторов конфигурации.

КонфигурацияЗначения квалификатораОписание
MCC и MNC Примеры:
mcc310
mcc310-mnc004
mcc208-mnc00
и т. д.

Мобильный код страны (mobile country code, MCC), за которым опционально идет код мобильной сети (mobile network code, MNC), прочитанный из SIM-карты устройства. Например, mcc310 соответствует U.S. (США) для любого оператора, mcc310-mnc004 соответствует U.S. оператора Verizon, mcc208-mnc00 соответствует France оператор Orange.

Если устройство использует соединение по радиоканалу (это телефон или смартфон GSM), значения MCC и MNC будут получены из симкарты.

Вы также можете использовать MCC отдельно (например, подключить в приложении привязанные к стране легальные ресурсы). Если Вам нужно задать ресурсы только на основании языка, то используйте вместо этого квалификатор языка и региона (language and region, об этом далее). Если Вы решили использовать квалификатор MCC и MNC, то должны это сделать с осторожностью и протестировать для проверки, что все работает так, как Вы ожидаете.

Также см. поля конфигурации mcc и mnc, которые показывают текущий мобильный код страны и код мобильной сети соответственно.

Язык и регион (Language, region) Примеры:
en
fr
en-rUS
fr-rFR
fr-rCA
и т. д.

Язык, который задаются двухбуквенным кодом ISO 639-1, за которым опционально идут две буквы ISO 3166-1-alpha-2 кода региона (перед которым стоит маленькая буква "r").

Коды не чувствительны к регистру букв (not case-sensitive); r в префиксе используется, чтобы четче отделить порцию данных региона. Вы не можете указать регион отдельно.

Во время жизни приложения язык может поменяться, если пользователь поменяет системные установки языка. См. Handling Runtime Changes для информации о том, как это может повлиять на приложение во время выполнения (runtime).

См. Localization для полного руководства по локализации Вашего приложения для других языков.

См. также поле конфигурации locale, которое показывает текущую установленную локаль.

Направление формирования интерфейса (Layout Direction) ldrtl
ldltr

Задает, как формируется развертка интерфейса для Вашего приложения (layout direction). ldrtl означает справа налево, "layout-direction-right-to-left". ldltr означает слева направо, "layout-direction-left-to-right" и это неявно заданное значение по умолчанию.

Эта установка может быть применена к любому ресурсу, такому как layouts, drawable или value.

Например, если Вы хотите предоставить некоторый специфичный layout для арабских пользователей (язык Arabic) и некоторые стандартные layout для другого "right-to-left" языка - типа Персидский (Persian), или Иврит (Hebrew) то нужно иметь:

res/
    layout/    main.xml (Default layout)
    layout-ar/   main.xml (Specific layout for Arabic)
    layout-ldrtl/   main.xml (Any "right-to-left" language, except
                  for Arabic, because the "ar" language qualifier
                  has a higher precedence.)

Примечание: чтобы разрешить фичу right-to-left layout для Вашего приложения, Вы должны установить supportsRtl в значение "true" и установить targetSdkVersion в 17 или больше.

Добавлено в API level 17.

smallestWidth (самая маленькая ширина) swdp

Примеры:
sw320dp
sw600dp
sw720dp
и т. д.

Фундаментальный размер экрана, как это показано самым маленьким размером, доступным на экране. В частности, параметр устройства smallestWidth является самым коротким доступным для экрана размером по высоте и ширине. Вы можете использовать этот квалификатор, чтобы гарантировать, что независимо от текущей ориентации экрана у Вашего приложения есть минимальный dps по ширине для Вашего интерфейса пользователя (UI).

Например, если Ваш layout требует всегда самый маленький размер на экране как минимум 600 dp, то Вы можете использовать этот квалификатор для создания ресурсов layout res/layout-sw600dp/. Система будет использовать эти ресурсы только когда будет доступна самая маленькая размерность ка минимум 600dp, независимо от того, является ли 600dp воспринятой пользователем высотой или шириной. Параметр smallestWidth является фиксированной характеристикой размера экрана устройства; smallestWidth не меняется, когда меняется ориентация экрана.

Параметр smallestWidth учитывает обрамление экрана и системный UI. Например, если устройство имеет на экране некоторые постоянные элементы интерфейса UI, которые составляют пространство по оси smallestWidth, то система декларирует smallestWidth меньше, чем актуальный размер экрана, потому что эти пикселы экрана не доступны для использования в пользовательском интерфейсе (UI) программы. Таким образом, этот параметр характеризует действительный минимальный размер, требуемый для Вашего layout (обычно это значение соответствует "минимальной ширине", которую поддерживает Ваш layout, независимо от текущей ориентации экрана).

Вот некоторые значения, которые моно использовать для общих размеров экрана:

  • 320, для устройств с конфигурацией экрана наподобие:
    • 240x320 ldpi (QVGA смартфон)
    • 320x480 mdpi (смартфон)
    • 480x800 hdpi (high density смартфон)
  • 480, для таких экранов, как 480x800 mdpi (планшет/смартфон).
  • 600, для таких экранов как 600x1024 mdpi (7" tablet).
  • 720, для таких экранов как 720x1280 mdpi (10" tablet).

Когда Ваше приложение предоставляет несколько директорий ресурсов с различными значениями для квалификатора smallestWidth, система будет использовать smallestWidth, ближайший к smallestWidth устройства (не превышая его).

Добавлено в API level 13.

Также см. атрибут android:requiresSmallestWidthDp, который декларирует минимальный smallestWidth, с которым совместимо Ваше приложение, и поле конфигурации smallestScreenWidthDp, которое содержит значение smallestWidth устройства.

Для дополнительной информации по использованию этого квалификатора для разработки под различные экраны, см. руководство разработчика Supporting Multiple Screens.

Доступная ширина wdp

Примеры:
w720dp
w1024dp
и т. д.

Указывает минимально доступную ширину экрана (screen width) в единицах dp, которую должен использовать ресурс - указано значение. Это конфигурационное значение поменяется, когда изменится ориентация экрана от landscape до portrait и наоборот, чтобы соответствовать реальной текущей ширине.

Когда приложение предоставляет различные директории ресурсов с разными значениями для этого параметра конфигурации, система использует ближайший (без превышения) к текущей ширине экрана устройства. Значение учитывает обрамления экрана, так что если устройства имеет некоторые постоянные элементы интерфейса UI по левому или правому краям дисплея, то будет использовано значение меньше, чем реальный физический размер экрана, учитывая размер этих элементов UI, уменьшающих доступное для приложения место.

Добавлено в API level 13.

См. также поле конфигурации screenWidthDp которое содержит текущую ширину экрана.

Для дополнительной информации по дизайну приложения для разных экранов с использованием этого квалификатора см. руководство разработчика Supporting Multiple Screens.

Доступная высота hdp

Примеры:
h720dp
h1024dp
и т. д.

Указывает минимально доступную высоту экрана (screen height) в единицах "dp", которую должен использовать ресурс - задано по величине. Эта конфигурационная величина изменится, когда поменяется ориентация экрана между landscape и portrait (и наоборот), чтобы соответствовать текущей реальной высоте.

Когда Ваше приложение предоставляет несколько директорий ресурсов с различными значениями для этой конфигурации, система использует ближайший (без превышения) к текущей высоте экрана. Значение здесь учитывает обрамления экрана, так что если устройство использует некоторые постоянные элементы интерфейса UI внизу или вверху экрана, то используемое значение высоты будет меньше реальной физической высоты экрана (будут учтены размеры этих элементов UI и доступное для приложение пространство уменьшится). Обрамления экрана, которые не фиксированы (такие как строка статуса status bar, которая может быть скрыта при работе приложения в полный экран) здесь не будут учитываться, не учитываются ни title bar, ни action bar - так что приложения должны быть подготовлены к тому, что доступное пространство может оказаться меньше, чем здесь указано.

Добавлено в API level 13.

Также см. поле конфигурации screenHeightDp, которое содержит текущую высоту экрана.

Для дополнительной информации по дизайну различных экранов с использование этого квалификатора см. руководство разработчика Supporting Multiple Screens.

Размер экрана (Screen size) small
normal
large
xlarge

small: маленькие экраны, которые имеют размер, аналогичный экрану low-density QVGA. Минимальный размер layout для маленького экрана приблизительно равен 320x426 dp. Примерами могут быть QVGA low density и VGA high density.

normal: нормальные экраны, которые соответствуют экрану medium-density HVGA. Минимальный размер layout для нормального экрана составляет примерно 320x470 dp. Примеры таких экранов WQVGA low density, HVGA medium density, WVGA high density.

large: большие экраны, которые имеют размер, аналогичный экрану medium-density VGA. Минимальный размер layout для большого экрана примерно 480x640 dp. Примеры таких экранов VGA и WVGA medium density.

xlarge: "очень большие" экраны, которые считаются бОльшими, чем традиционный экран medium-density HVGA. Минимальный размер layout для экрана xlarge составляет примерно 720x960 dp. В большинстве случаев устройства с "очень большими" экранами будут слишком велики, чтобы их можно было носить в кармане, и вероятнее всего это будут устройства типа планшета. Добавлено в API level 9.

Примечание: использование квалификатора размера экрана не подразумевает, что ресурс предназначен для устройства с экраном именно такого размера. Если Вы не предоставили альтернативных ресурсов с квалификаторами, которые лучше соответствует текущей конфигурации устройства, система может использовать ресурс, который подходит лучше всего по алгоритму best match (см. далее).

Внимание: если Ваши ресурсы используют квалификатор размера больше, чем у текущего экрана, то система не будет использовать его для Вашего приложения, и завершится по ошибке (crash at runtime, например, если все layout ресурсы помечены квалификатором xlarge, но устройство имеет экран "нормального" размера).

Добавлено в API level 4.

Дополнительную информацию см. в Supporting Multiple Screens.

Также см. поле конфигурации screenLayout, которое показывает какой сейчас экран - small, normal или large.

Соотношение сторон экрана (Screen aspect) long
notlong
  • long: длинные экраны, такие как WQVGA, WVGA, FWVGA
  • notlong: не длинные экраны, такие как QVGA, HVGA, and VGA

Добавлено в API level 4.

Этот параметр основывается просто на соотношении сторон экрана (экран "long" будет шире). Это не связано с ориентацией экрана.

Также см. поле конфигурации screenLayout, которое показывает какой экран (является ли он длинным, long).

Ориентация экрана port
land
  • port: устройства с портретной ориентацией (расположение экрана вертикальное)
  • land: устройства с пейзажной ориентацией (расположение экрана горизонтальное)

Это может поменяться в течение жизни приложения, если пользователь повернул экран. См. Handling Runtime Changes (обработка изменений во время выполнения) для информации о том, как это повлияет на приложение во время выполнения.

Также см. поле конфигурации orientation, которое показывает текущую ориентацию экрана устройства.

Режим интерфейса пользователя (UI mode) car
desk
television
appliance
  • car: устройство работает в док-отсеке автомобиля (car dock)
  • desk: устройство работает в док-станции (desk dock)
  • television: устройство работает на отображение для телевидения, предоставляя десятишаговый интерфейс "ten foot", где UI рассчитан на большой экран, от которого пользователь находится на большом расстоянии, и ориентирован на использование DPAD или другой орган управления, отличный от касания к экрану.
  • appliance: устройство работает как прибор без дисплея

Добавлено в API level 8, режим television добавлен в API 13.

Информацию о том, как приложение может отвечать на события установки в док и извлечения из дока, читайте Determining and Monitoring the Docking State and Type.

Этот параметр может поменяться во время жизни приложения, если пользователь поместит устройство в док. Вы можете разрешить или запретить некоторые из этих режимов c использованием UiModeManager. См. Handling Runtime Changes для информации от том, как это может повлиять на приложение во время его выполнения (runtime).

Ночной режим (Night mode) night
notnight
  • night: ночное время
  • notnight: дневное время

Добавлено в API level 8.

Это может поменяться в течение жизни Вашего приложения, если ночной режим остался в режиме auto mode (по умолчанию), в этом случае режим поменяется в соответствии с текущим временем. Вы можете разрешить или запретить этот режим с использованием UiModeManager. См. Handling Runtime Changes для информации от том, как это изменение режима может повлиять на Ваше приложения во время его выполнения (runtime).

Плотность точек на экране, разрешающая способность экрана (Screen pixel density, в единицах dpi) ldpi
mdpi
hdpi
xhdpi
nodpi
tvdpi
  • ldpi: экраны с низкой плотностью точек (Low-density screens); это примерно 120dpi.
  • mdpi: экраны средней плотности точек (Medium-density, на традиционном HVGA); примерно 160dpi.
  • hdpi: экраны с высокой плотностью (High-density screen); примерно 240dpi.
  • xhdpi: экраны с очень высокой плотностью (Extra high-density screen); примерно 320dpi. Добавлено в API Level 8
  • nodpi: этот квалификатор можно использовать для ресурсов bitmap (растровая картинка), которую Вы не хотели бы масштабировать для соответствия плотности экрана устройства.
  • tvdpi: экраны, находящиеся где-то между mdpi и hdpi; примерно 213dpi. Этот квалификатор не считается "главной" группой для плотности экрана. Часто предназначено для телевидения и для большинства приложений этот квалификатор не нужен - предоставление ресурсов mdpi и hdpi вполне достаточно для большинства приложений и система сделает масштабирование так, как это необходимо. Этот квалификатор добавлен в API level 13.

Имеется соотношение размеров 3:4:6:8 между четырьмя основными плотностями экрана (игнорируя плотность tvdpi). Таким образом, если картинка 9x9 в ldpi, то она будет 12x12 в mdpi, 18x18 в hdpi и 24x24 в xhdpi.

Если Вы считаете, что отображаемые приложением картинки плохо выглядят на режимах телевизора или других устройствах, и хотите попробовать использовать ресурсы tvdpi resources, то фактор масштабирования будет 1.33*mdpi. Например, если есть картинка 100px x 100px для экранов mdpi, то она должна быть в разрешении 133px x 133px для tvdpi.

Примечание: использование квалификатора плотности не подразумевает, что ресурс предназначен только лишь для экранов с такой указанной плотностью. Если Вы не предоставили альтернативные ресурсы с квалификаторами, которые лучше подходят к текущей конфигурации устройства, система все равно выберет самые подходящие ресурсы по алгоритму наилучшего соответствия, см. ниже best match.

См. Supporting Multiple Screens для дополнительной информации от том, как поддерживать разные плотности экранов и как Android может масштабировать Ваши растровые изображения (bitmap), чтобы они укладывались с текущую плотность экрана.

Тип тачскрина notouch
finger
  • notouch: устройство не имеет тачскрина.
  • finger: устройство имеет тачскрин, который предназначен для взаимодействия с пальцами пользователя.

См. также поле конфигурации touchscreen, которое показывает тип тачскрина на устройстве.

Наличие клавиатуры keysexposed
keyshidden
keyssoft
  • keysexposed: устройство имеет доступную клавиатуру. Если устройство имеет разрешенную программно организованную клавиатуру (что скорее всего), это может использоваться даже если реальная клавиатура недоступна, или даже если отсутствует физическая клавиатура. Если программная клавиатура не доступна, или она запрещена, то то это будет использоваться только в случае наличия аппаратной клавиатуры.
  • keyshidden: устройство имеет аппаратную клавиатуру, но она скрыта, и в устройстве не разрешена программная клавиатура.
  • keyssoft: устройство имеет разрешенную программную клавиатуру независимо от того, видима она или нет.

Если Вы предоставили ресурсы keysexposed, не не предоставили ресурсов keyssoft, система использует ресурсы keysexposed независимо от того, видима клавиатура или нет, пока в системе разрешена программная клавиатура.

Это можно поменяться в течение жизни приложения, если пользователь открыл аппаратную клавиатуру. См. Handling Runtime Changes для информации о том, как это повлияет но Ваше приложение во время его выполнения (runtime).

Также см. поля конфигурации hardKeyboardHidden и keyboardHidden, которые показывают соответственно видимость аппаратной клавиатуры и видимость клавиатуры любого вида (включая программную).

Главный метод ввода текста (Primary text input method) nokeys
qwerty
12key
  • nokeys: устройство не имеет аппаратных кнопок для ввода текста.
  • qwerty: устройство имеет аппаратную клавиатуру qwerty, независимо от того, видна она для пользователя, или нет.
  • 12key: устройство имеет аппаратную 12-key клавиатуру, независимо от того, видна она для пользователя или нет.

См. также поле конфигурации keyboard, которое показывает доступный главный метод ввода текста.

Версия платформы (Platform Version, API level) Примеры:
v3
v4
v7
и т. д.

API level, поддерживаемый устройством. Например, v1 соответствует API level 1 (устройства с Android 1.0 или выше), и v4 соответствует API level 4 (устройства с Android 1.6 или выше). См. документ Android API levels для получения дополнительной информации по этим значениям.

Примечание: некоторые квалификаторы конфигурации были добавлены после выхода Android 1.0, так что не все версии могут поддерживать все квалификаторы. Использование нового идентификатора неявно добавляет квалификатор версии платформы, так что старые устройства могут игнорировать его. Например, использование квалификатора w600dp автоматически подключит квалификатор v13, поскольку доступный квалификатор ширины был новым в API level 13. Чтобы избежать любых проблем, всегда подключайте набор ресурсов по умолчанию (т. е. набор ресурсов без квалификаторов). Дополнительную информацию см. далее в разделе "Предоставление наилучшей совместимости устройств с помощью ресурсов".

[Правила имен квалификаторов]

Здесь приведены некоторые правила по использованию имен квалификаторов конфигурации:

• Вы можете указать несколько квалификаторов для одного набора ресурсов. При этом в имени подкаталога эти квалификаторы должны отделяться друг от друга дефисами. Например, drawable-en-rUS-land будут применены для англоязычных (US-English) устройств в горизонтальной (landscape) ориентации экрана.

• Квалификаторы должны быть указаны в том же самом порядке, в каком они появляются в таблице 2. Например, здесь квалификаторы указаны неправильно: drawable-hdpi-port/,
а здесь правильно: drawable-port-hdpi/

• Директории альтернативных ресурсов не могут вкладываться друг в друга. Например, Вы не можете иметь такую систему подкаталогов ресурсов: res/drawable/drawable-en/.

• Значения чувствительны к регистру символов (case-insensitive). Компилятор ресурсов перед обработкой конвертирует имена директорий в нижний регистр (lower case, маленькие буквы), чтобы избежать проблем на файловых системах, которые нечувствительны к регистру символов (case-insensitive file system; к примеру, такими системами являются FAT и NTFS). Любые заглавные имена в именах только улучшают читаемость.

• Для каждого типа идентификатора поддерживается только одно значение. Например, если Вы хотите использовать одинаковые drawable-файлы для Испании (Spain) и для Франции (France), то Вы не можете иметь каталоги, именованные drawable-rES-rFR/. Вместо этого нужны две директории ресурсов, такие как drawable-rES/ и drawable-rFR/, в каждой из которых содержаться подходящие файлы. Однако не требуется дублировать те же самые файлы в обоих подкаталогах. Вместо этого Вы можете создать псевдоним (alias) ресурса. См. далее раздел "Создание псевдонимов ресурсов".

После того, как Вы сохранили альтернативные ресурсы в директориях, именованных с этими квалификаторами, Android автоматически применит эти ресурсы в Вашем приложении, основываясь на текущей конфигурации устройства. Каждый раз, когда запрашивается ресурс, Android проверяет директории альтернативных ресурсов, которые содержат запрашиваемый файл ресурса, затем находит наиболее подходящий ресурс (этот процесс рассмотрен ниже). Если не найдены альтернативные ресурсы, которые подходят к частной текущей конфигурации устройства, то Android использует соответствующие ресурсы по умолчанию (это набор ресурсов, для которых отдельные типы ресурсов не содержат квалификаторов в именах своих подкаталогов).

[Создание псевдонимов ресурсов (resource alias)]

Когда у Вас есть ресурс, который Вы хотите использовать не только в одной конфигурации, а нескольких (но не хотите этот ресурс использовать в качестве ресурса по умолчанию), то Вам не нужно делать его копии и помещать эти копии в директории для альтернативных ресурсов. Вместо этого Вы можете (в некоторых случаях) создать альтернативный ресурс, который будет работать как псевдоним (alias) для ресурса, сохраненного в Вашей директории ресурсов по умолчанию.

Внимание: не все ресурсы имеют механизм для создания алиасов на другой ресурс. В частности animation, menu, raw и другие не указанные ресурсы (unspecified resources) в директории xml/ не предоставляют такую возможность.

Представим себе, что Вы имеете иконку приложения icon.png, и Вам нужна её уникальная версия для разных языков (установок локали). Однако две локали English-Canadian и French-Canadian должны использовать одну и ту же версию иконки. Вы можете решить сделать копию той же самой картинки как в директорию ресурсов для English-Canadian, так и в директорию для French-Canadian, но это будет неправильным (хотя бы с точки зрения экономия места на диске). Вместо копирования Вы можете сохранить картинку, которая используется в обоих случаях, в виде файла наподобие icon_ca.png (можно использовать любое имя кроме icon.png), поместить этот файл в директорию по умолчанию res/drawable/. Затем создайте файл icon.xml в каталоге res/drawable-en-rCA/ и в каталоге res/drawable-fr-rCA/, и сделайте в них ссылку на ресурс icon_ca.png, используя элемент < bitmap >. Это позволяет Вам сохранить только одну версию файла PNG, и два маленьких текстовых файла XML, которые указывают на него. Ниже приведен пример такого файла XML.

Ресурс Drawable

Для создания алиаса на существующий drawable, используйте элемент < bitmap >. Например:

< ?xml version="1.0" encoding="utf-8"? >
< bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/icon_ca" />

Если Вы сохраните этот XML в файл icon.xml (в директории альтернативных ресурсов, такой как res/drawable-en-rCA/), то он будет скомпилирован в ресурс, к которому можно обращаться как к R.drawable.icon, но в действительности это будет алиас на ресурс R.drawable.icon_ca (который сохранен в каталоге res/drawable/).

Ресурс Layout

Чтобы создать алиас на существующий layout, используйте элемент < include >, обернутый в < merge >. Например:

< ?xml version="1.0" encoding="utf-8"? >
< merge >
    < include layout="@layout/main_ltr" />
< /merge >

Если Вы сохраните этот XML в файл main.xml, то он будет скомпилирован в ресурс, к которому можно обращаться как к R.layout.main, но в действительности это будет алиас на ресурс R.layout.main_ltr.

Ресурсы строк (Strings) и другие простые значения

Чтобы создать алиас для существующей строки, просто используйте resource ID требуемой строки в качестве значения для новой строки. Например:

< ?xml version="1.0" encoding="utf-8"? >
< resources >
    < string name="hello">Hello< /string >
    < string name="hi">@string/hello< /string >
< /resources >

Ресурс R.string.hi теперь будет алиасом для R.string.hello.

Другие простые значения работают таким же образом. Вот пример для цвета (color):

< ?xml version="1.0" encoding="utf-8"? >
< resources >
    < color name="yellow">#f00< /color >
    < color name="highlight">@color/red< /color >
< /resources >

[Предоставление наилучшей совместимости устройств с помощью ресурсов]

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

Например, если Ваше приложение поддерживает несколько языков, всегда добавляйте директорию values/ (в которой будут сохранены Ваши строки) без квалификатора языка и региона. Если вы вместо этого поместите Ваши строки в директории, которые имеют квалификаторы языка и региона, то Ваше приложение завершится с ошибкой при запуске на устройстве, у которого установлен язык, не поддерживаемый Вашими строками. Однако если Вы предоставите ресурсы по умолчанию values/, то Ваше приложение сможет правильно запуститься (даже если пользователь не поймет ничего в интерфейсе, это всегда лучше краха приложения).

Аналогично, если Вы предоставите разные layout-ресурсы, базируясь на ориентации экрана, Вы все равно должны выбрать одну ориентацию в качестве ориентации по умолчанию. Например, вместо того, чтобы предоставить ресурсы layout в каталогах layout-land/ для пейзажной ориентации (landscape) и layout-port/ для портретной ориентации (portrait), оставьте одну в качестве ориентации по умолчанию, такую как layout/ для ориентации landscape и layout-port/ для ориентации portrait.

Предоставлять ресурсы по умолчанию важно не только потому что Ваше приложение может работать на конфигурации Android, которую Вы не ожидали, но также и потому, что новые версии Android иногда добавляют квалификаторы конфигурации, которые старые версии не поддерживают. Если Вы используете новый квалификатор ресурса, но поддерживаете совместимость кода со старыми версиями Android, то когда старая версия Android запустит Ваше приложение, оно рухнет, если Вы не предоставите ресурсы по умолчанию, потому что не сможет использовать имена ресурсов с новым квалификатором. Например, если Ваша minSdkVersion установлена в 4, и Вы квалифицируете все Ваши drawable-ресурсы с использованием ночного режима (night mode, night или notnight, которые были добавлены в API Level 8), то устройство на системе API level 4 не сможет получить доступ к Вашим drawable-ресурсам и завершится по ошибке. В этом случае Вы можете захотеть использовать в качестве ресурса по умолчанию notnight, так что Вам нужно исключить этот квалификатор для drawable-ресурсов, которые находятся либо в drawable/, либо в drawable-night/.

Таким образом, чтобы предоставить наилучшую совместимость для устройств, всегда предоставляйте ресурсы по умолчанию (default resources) для тех ресурсов, которые нужны Вашему приложению, чтобы оно могло правильно работать. Затем создайте альтернативные ресурсы для отдельных конфигураций устройств, используя квалификаторы конфигурации.

Есть только одно исключение из этого правила: если minSdkVersion Вашего приложения 4 или больше, то Вам не нужно иметь drawable-ресурсы по умолчанию, когда Вы предоставили альтернативные drawable-ресурсы с квалификатором плотности экрана (screen density qualifier). Даже без drawable-ресурсов по умолчанию Android может найти лучший вариант альтернативных плотностей экрана, и смасштабировать картинки как это требуется. Однако, для лучшей поддержки на всех типов устройств Вы должны предоставить альтернативные drawable-ресурсы для всех трех типов плотностей экрана.

[По какому принципу Android находит самый подходящий ресурс]

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

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

И предположим, что устройство имеет следующую конфигурацию:

Locale (язык) = en-GB
Ориентация экрана портретная = port
Screen pixel density (плотность пикселов экрана) = hdpi
Тип тачскрина = notouch
Главный метод текстового ввода = 12key

Путем сравнения конфигурации устройства с доступными альтернативными ресурсами, Android выберет в такой ситуации рисуемые ресурсы из drawable-en-port.

Android-Providing-Resources-best-matching-flowchart-fig2
Рис. 2. Диаграмма, показывающая алгоритм выбора
наилучшего ресурса для приложения.

Когда система принимает решение о том, какой ресурс выбрать, она придерживается следующей логики:

1. Отбрасываются ресурсы, которые противоречат конфигурации устройства. Для нашего примера директория drawable-fr-rCA/ будет отброшена, потому что противоречит установленной локали en-GB.

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

Исключение из правила: плотность пикселов на экране является единственным квалификатором, который не отбрасывается из за противоречия с конфигурацией. Даже если плотность экрана устройства hdpi, директория drawable-port-ldpi/ не будет отброшена, потому что в этой точке принимается решение, что любое разрешение подходит. Дополнительную информацию см. в документе Supporting Multiple Screens.

2. Выбирается в списке следующий по важности квалификатор (список согласно таблице 2). Просмотр списка начинается с квалификатора MCC, и далее просмотр переходит все ниже и ниже по списку.

3. Делается проверка: указан ли в имени какой-либо директории этот квалификатор? Если нет, то переход на шаг 2, и продолжение просмотра списка. Если да, то продолжить с шага 4.

4. Отбрасываются ресурсы, которые не включают этот квалификатор. В нашем примере система отбросит все директории ресурсов, которые не включают квалификатор языка:

drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

Исключение из правила: если рассматриваемый квалификатор плотность экрана, то Android выбирает самую близко подходящую к устройству плотность экрана. В целом Android предпочитает уменьшить масштаб бОльшего исходного изображения вместо увеличения масштаба меньшего исходного изображения. См. Supporting Multiple Screens.

5. Происходит возврат назад и повторяются шаги 2, 3 и 4, пока не останется только одна директория. В нашем примере ориентация экрана оказывается следующим квалификатором, для которого есть любые соответствия. Таким образом, ресурсы с не указанной ориентацией экрана будут отброшены:

drawable-en/
drawable-en-port/
drawable-en-notouch-12key/

В результате осталась только конфигурация drawable-en-port.

Через эта процедуру проходит каждый запрашиваемый ресурс, но система оптимизирует некоторые аспекты. Одна их таких оптимизаций - могут быть отброшены альтернативные ресурсы, которые никогда не будут подходить. Например, если язык конфигурации English ("en"), то любая директория, которая содержит в имени другой квалификатор, никогда не попадет в пул опрашиваемых ресурсов (хотя директории ресурсов без квалификатора языка все еще будут в опрашиваемом пуле).

Когда происходит выбор ресурсов на основе квалификаторов размера экрана, система будет использовать ресурсы, разработанные для экранов меньшего размера, чем текущий экран, если нет ресурсов с совпадением лучше (например, если необходимо, то экраны с большим размером будут использовать ресурсы экрана с нормальным размером). Однако если единственные имеющиеся ресурсы будут предназначены для экрана больше, чем текущий, то система не будет их использовать, и Ваше приложение завершится с ошибкой, если никакие другие ресурсы не подойдут для текущей конфигурации (например, если все layout-ресурсы помечены квалификатором xlarge, но устройство имеет экран с размером normal).

Примечание: приоритет квалификатора (согласно таблице 2) более важен, чем количество квалификаторов, которые полностью соответствуют устройству. К примеру на шаге 4 последний выбор в списке включает три квалификатора, которые полностью соответствуют устройству (ориентация экрана, тип тачскрина, метод ввода), в то время как drawable-en совпадает только по одному параметру (язык). Однако, поскольку язык имеет согласно таблице 2 приоритет выше (он находится ближе к началу таблицы), чем эти другие квалификаторы, то конфигурация drawable-port-notouch-12key будет отброшена.

Чтобы узнать больше о том, как использовать ресурсы в приложении, см. [3].

[Ссылки]

1. Providing Resources site:developer.android.com.
2. Типы ресурсов приложения Android.
3. Получение доступа к ресурсам приложения Android.
4. AnimationDrawable: создание анимированной кнопки.
5. Словарик Android.