Как работает «? Android: attr / activateBackgroundIndicator»?

86

Я искал, как выделить выбранный элемент в списке при отображении контекстной панели действий для выбора, и решение, которое я нашел, заключалось в том, чтобы установить android:backgroundатрибут xml макета строки на "?android:attr/activatedBackgroundIndicator".

Как же это работает?

  1. какой механизм задействован?
  2. что означают такие элементы синтаксиса, как «?», «attr», «activateBackgroundIndicator»?
  3. где определяется значение "activateBackgroundIndicator"?
Джархатх
источник

Ответы:

221

Если вы настроены криминалистически, вот как выкопать и узнать, что происходит.

android:background="?android:attr/activatedBackgroundIndicator"?

Интуитивно это означает, что фон должен быть доступен для рисования.

Но давайте разберем это дальше, чтобы увидеть, как мы добираемся до нашего загадочного drawable.

Если быть точным, это означает «установить для атрибута фона то, на что ссылается атрибут« activateBackgroundIndicator » в текущей теме .

Если вы понимаете часть «относится к текущей теме», вы в основном понимаете все, что происходит за кулисами.

По сути, activateBackgroundIndicator не является фактическим объектом для рисования, а является ссылкой на объект для рисования . Так где же на самом деле определяется атрибут «activateBackgroundIndictor»?

Он определен в вашем каталоге sdk в имени файла attrs.xml . Например:

путь_к_андроид_сдк / платформы / android-17 / данные / res / значения / attrs.xml

Если вы откроете этот файл, вы увидите следующее объявление:

<attr name="activatedBackgroundIndicator" format="reference" />

attrs.xml - это место, где вы объявляете все атрибуты, которые позже собираетесь использовать в своем представлении xml. Обратите внимание, что мы объявляем атрибут и его тип, а не присваиваем здесь значение .

Фактическое значение задается в themes.xml . Этот файл находится по адресу:

путь_к_андроид_сдк / платформы / android-17 / данные / res / значения / themes.xml

Если вы откроете этот файл, вы увидите несколько определений в зависимости от того, какую тему вы используете . Например, вот определения для названия темы Theme, Theme.Light, Theme.Holo, Theme.Holo.Light соответственно:

<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>

Теперь у нас есть загадочные чертежи. Если вы выберете первый, он будет определен в папке с возможностью переноса по адресу:

путь_к_андроид_сдк / платформы / android-17 / данные / res / вытяжка / активированный_background.xml

Если вы откроете этот файл, вы увидите определение drawable, которое важно для понимания того, что происходит.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
    <item android:drawable="@color/transparent" />
</selector>

Здесь мы определяем чертеж с двумя состояниями - состояние по умолчанию - это просто прозрачный фон, а если состояние - «state_activated», то наш чертеж - «list_selector_background_selected».

см. эту ссылку для получения справочной информации о чертежах и состояниях.

list_selector_background_selected - это png-файл с исправлениями 9, который находится в папке drawable-hdpi.

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

Нуман Салати
источник
3
Один ответ, чтобы править всеми. В общем, если бы кто-то создавал XML с теми же селекторами, он мог бы создать свой собственный «activateBackgroundIndicator»?
Gee.E 03
1
точно - вы можете переопределить его в своем настраиваемом theme.xml b / c его ссылочным атрибутом.
Нуман Салати 03
Этот ответ помог мне понять, как установить настраиваемый объект для рисования в моем элементе списка ящика навигации.
Tastybrownies
Это отличный ресурс для начала работы над индивидуальной selectorработой с использованием чертежей. Прочитав это, я использовал Документы атрибутов стиля, чтобы заполнить оставшиеся части.
Маурицио
1
Не могли бы вы привести пример того, как переопределить этот фоновый индикатор? Моя не работает: / <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> <item name = "android: activeBackgroundIndicator"> @ drawable /active_background </item> </style> active_background.xml : <selector xmlns: android = " schemas.android.com/apk/res/android "> <item android: state_activated = "true" android: drawable = "@ color / yellow" /> <item android: drawable = "@ android: color / transparent "/> </selector>
vandus
13

Я тоже задавался вопросом об этом в какой-то момент. Большая часть ресурсов Android кажется черным ящиком и не может быть видна напрямую. Мне может где-то их не хватать, но я не могу найти их в исходном коде SDK. Вот что я знаю.

  • android:background займет вытяжку.
  • Синтаксис в стиле

    Должна быть ссылка на другой ресурс в форме «@ [+] [package:] type: name» или на атрибут темы в форме «? [Package:] [type:] name»

В этом случае ?означает, что нужно посмотреть на тему в пакете, androidи она имеет тип, в attrкотором указано ее имя activatedBackgroundIndicator.

Вы также должны иметь доступ к этому в коде программной части с помощью android.R.attr.activatedBackgroundIndicator.

Список attrсвойств Android можно найти на R.attr.

  • activatedBackgroundIndicator - это определенная возможность рисования в Android 3.0+ как

    Drawable используется в качестве фона для активированных элементов.

По сути, это просто стандартный элемент, определенный в ОС. Я не могу найти в исходниках Android, но вот ссылка на документацию. activeBackgroundIndicator

Кирк
источник
5

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

Это дает возможность повторно использовать значения ресурсов. Я говорю не о производительности, а об организации и обслуживании. Атрибут действует как переменная с обещанием, что он будет хранить фактическое значение во время выполнения.

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

  1. Создайте свою собственную тему (которая представляет собой просто причудливое название ресурса «стиль»), чаще всего на основе одной из тем по умолчанию.
  2. Укажите собственное значение для рассматриваемого атрибута.

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

редактировать

Следует отметить фактические имена атрибутов и их существование в различных версиях платформы. Довольно часто новые атрибуты вводятся в следующих версиях платформы - например, некоторые из них были добавлены в версии 3.0 с целью стилизации ActionBar.

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

андр
источник
2

Обновление: в Руководстве по API доступна более подробная версия, поэтому я хотел бы процитировать ее.

Ресурс атрибута стиля позволяет вам ссылаться на значение атрибута в применяемой в данный момент теме. Ссылка на атрибут стиля позволяет вам настроить внешний вид элементов пользовательского интерфейса, стилизовав их в соответствии со стандартными вариантами, предоставляемыми текущей темой, вместо того, чтобы указывать жестко заданное значение. Ссылка на атрибут стиля по существу означает: «использовать стиль, определенный этим атрибутом, в текущей теме».

Для ссылки на атрибут стиля синтаксис имени почти идентичен обычному формату ресурса, но вместо символа at (@) используйте знак вопроса (?), А часть типа ресурса является необязательной. Например: `

Оригинальный ответ:

numan salati уже предложил идеальный ответ, но не обратился к "?" синтаксис. Вот цитата из Руководства по API Доступ к ресурсам

Для ссылки на атрибут стиля синтаксис имени почти идентичен обычному формату ресурса, но вместо символа at (@) используйте знак вопроса (?), А часть типа ресурса является необязательной. Например:

? [<имя_пакета>:] [<тип_ресурса> /] <имя_ресурса>

Тэн Пао Ю
источник