Несоответствия в выборе ресурсов Android и их значениях
Проблема, с которой я сталкиваюсь, указывает на то, что корзина ресурсов выбирается для данного действия. layout
XML несовместим с ресурсами, выбранными из values
папка, несмотря на одинаковые квалификаторы ресурса, используемые в каждом наборе папок.
пример
После помещения некоторого регистрационного кода в абстрактную родительскую активность моего приложения я вижу, что при запуске моего приложения через эмулятор типа Nexus 7 (Android 4.1) наименьшая ширина действительно составляет 600dp, layout-sw600dp-*
папка используется для получения пользовательского интерфейса для действия, но папка, используемая для values
является values-large-*
, Я ожидал, что это будет values-sw600dp-*
таким образом, предоставляя мне жизненно важную информацию о том, под каким ресурсом ведется деятельность.
Код, ведущий запись в родительской активности моего приложения для всех android.app.Activity
s
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Configuration config = getResources().getConfiguration();
Log.i(this.getClass().getSimpleName(), String.format("Smallest width is [%s]", config.smallestScreenWidthDp));
configurationContext = SupportedDeviceConfiguration.fromResourceQualifer(getString(string.resourceQualifier));
Log.i(this.getClass().getSimpleName(), String.format("Running under the [%s] configuration context.", configurationContext.getResourceQualifier()));
...
Регистрация выходных данных, когда я запускаю этот код на устройстве типа Nexus 7;
[Logging fluff] Smallest width is [600]
[Logging fluff] Running under the [layout-large-land] configuration context.
Я знаю, о чем вы думаете - откуда взялась эта деривация макетов больших земель? Читать дальше...
Фон
Я пробую подход, изложенный здесь, который позволил бы мне проверять ресурсы, используемые во время выполнения. По сути, реализованный мною подход имеет следующую структуру квалификаторов ресурсов;
- res
+ layout // Default portrait layout.
+ layout-land // Default landscape layout
+ layout-large-land // pre 3.2 phablet landscape layout (Galaxy Note at v2.3.3)
+ layout-xlarge-land // pre 3.2 tablet landscape layout
+ layout-xlarge-port // pre 3.2 tablet portrait layout
+ layout-sw520dp-port // post 3.1 phablet portrait layout (Galaxy Note at v4.0.3)
+ layout-sw520dp-land // post 3.1 phablet landscape layout
+ layout-sw600dp-port // post 3.1 mini-tablet portrait layout (Nexus 7)
+ layout-sw600dp-land // post 3.1 mini-tablet-landscape layout
+ layout-sw700dp-port // post 3.1 tablet portrait layout
+ layout-sw700dp-land // post 3.1 tablet landscape layout
- values // Contains the root strings.xml
strings.xml
- values-land
default-config.xml
- values-large-land
default-config.xml
- values-xlarge-land
default-config.xml
- values-xlarge-port
default-config.xml
- values-sw520dp-port
default-config.xml
- values-sw520dp-land
default-config.xml
- values-sw600dp-port
default-config.xml
- values-sw600dp-land
default-config.xml
- values-sw700dp-port
default-config.xml
- values-sw700dp-land
default-config.xml
Так по сути values
классификаторы отражают это из layout
классификаторы. Под каждым из values-*
папки, которые я определил один файл под названием XML device-config.xml
с содержанием;
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="resourceQualifier">layout-{qualifier of values folder}</string>
</resources>
Так, например, values-sw600dp-land
подпапке device-config.xml
содержит одну строку со значением layout-sw600dp-land
, Цель в том, чтобы мой код оставался синхронизированным с макетами ресурсов, отображаемыми на экране. Это необходимо для того, чтобы мой код не выключал "поиск по идентификатору" какого-либо элемента, которого нет в отображаемом макете из-за задействованной недвижимости.
(Необязательно) Более глубокое обоснование того, почему я делаю это
Более глубокие причины, по которым мне хотелось бы знать, какой сегмент памяти используется во время выполнения, возникли из-за осознания того, что мой код с одним фрагментом для всех конфигураций становится сложным для управления с помощью различной логики на основе коммутатора, которая была непрозрачной и часто дублировала функции другие макеты... как будто мне нужно какое-то наследование фрагментов... что, если вы перейдете по ссылке, это именно то, что я и сделал. Недостатком этого является то, что мне нужно знать, с каким экраном я работаю, прежде чем дать указание платформе создать экземпляр фрагмента x, y или z, поскольку известно, что создаваемый фрагмент никогда не будет синхронизирован с макетом, который он использует. предназначен для раздувания. Это наследование работает и позволяет получить гораздо более управляемый стек фрагментов (Сонар тоже счастливее, что приятно).
Резюме
Тем не менее, я был потрясен этим очевидным несоответствием между тем, какая папка макета и папка значений выбирается фреймворком. Каждый из них имеет одинаковые квалификаторы, поэтому почему активность не использует layout-sw600dp-land
Пользовательский интерфейс XML использует values-sw600dp-land
ресурс? Я надеюсь, что у меня что-то не так, потому что это было самое лучшее из потенциальных решений, опубликованных в обсуждении SO, на которое я ссылался выше.
2 ответа
Я уверен, что вы имеете дело с приоритетом ресурсов, используемых для выбора.
Если вы предоставляете папки:
layout-sw600dp-*
values-large-*
values-sw600dp-*
Android не обязан сопоставлять папку выбора значений с макетом, скорее он использует ту же логику приоритета отдельно для макета и отдельно для папки значений.
Вы можете узнать об этом алгоритме выбора здесь: http://developer.android.com/guide/topics/resources/providing-resources.html
Я делаю приложение для Android 4.0.3. если вы используете sw600dp, sw720dp, необходимо использовать следующее?: - values-sw600dp-port default-config.xml
- values-sw600dp-land default-config.xml
- values-sw700dp-port default-config.xml
- values-sw700dp-land default-config.xml, потому что я не использую res/values-XXX и, похоже, работает нормально.