Ответ 1
Примечание. Использование библиотеки поддержки Android v22.1.0 и таргетинга уровня API 11 и выше? Прокрутите список до последнего обновления.
Мой стиль приложения установлен в Theme.Holo, который темный, и я бы как флажки в моем списке, чтобы быть в стиле Theme.Holo.Light. Я не пытаюсь создать собственный стиль. Код ниже не выглядит работать, ничего не происходит вообще.
Вначале может быть неясно, почему система проявляет это поведение, но когда вы действительно смотрите на механику, вы можете легко ее вывести. Позвольте мне провести вас шаг за шагом.
Во-первых, давайте посмотрим, что определяет стиль Widget.Holo.Light.CompoundButton.CheckBox
. Чтобы сделать вещи более ясными, я также добавил определение "обычного" (не светлого) стиля.
<style name="Widget.Holo.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />
<style name="Widget.Holo.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />
Как вы можете видеть, обе являются пустыми объявлениями, которые просто переносят Widget.CompoundButton.CheckBox
в другое имя. Поэтому давайте посмотрим на этот родительский стиль.
<style name="Widget.CompoundButton.CheckBox">
<item name="android:background">@android:drawable/btn_check_label_background</item>
<item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
</style>
Этот стиль ссылается как на фоновый рисунок, так и на кнопку. btn_check_label_background
- это просто 9-патч и, следовательно, не очень интересно по этому вопросу. Тем не менее, ?android:attr/listChoiceIndicatorMultiple
указывает, что некоторый атрибут, основанный на текущей теме (это важно для реализации), определит фактический вид CheckBox
.
Поскольку listChoiceIndicatorMultiple
является атрибутом темы, для него вы найдете несколько деклараций - по одной для каждой темы (или нет, если она унаследована от родительской темы). Это будет выглядеть следующим образом (с другими атрибутами, опущенными для ясности):
<style name="Theme">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
...
</style>
<style name="Theme.Holo">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_dark</item>
...
</style>
<style name="Theme.Holo.Light" parent="Theme.Light">
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_light</item>
...
</style>
Итак, это, когда происходит настоящая магия: на основе атрибута listChoiceIndicatorMultiple
, определяется фактический вид CheckBox
. Явление, которое вы видите, теперь легко объясняется: поскольку внешний вид основан на стиле (и не на основе стиля, потому что это просто пустое определение), и вы наследуете от Theme.Holo
, вы всегда получите внешний вид CheckBox
, соответствующий теме.
Теперь, если вы хотите изменить внешний вид CheckBox
на версию Holo.Light, вам нужно будет взять копию этих ресурсов, добавить их в свои локальные активы и использовать собственный стиль для их применения.
Что касается вашего второго вопроса:
Также вы можете устанавливать стили для отдельных виджетов, если вы устанавливаете стиль для приложения?
Абсолютно, и они переопределят любые стили, связанные с деятельностью или приложением.
Есть ли способ установить тему (стиль с изображениями) на флажок виджет. (...) Можно ли использовать этот селектор: ссылка?
Update:
Позвольте мне еще раз сказать, что вы не должны полагаться на внутренние ресурсы Android. Существует причина, по которой вы не можете просто получить доступ к внутреннему пространству имен, как вам удобно.
Однако способ доступа к системным ресурсам в конце концов - это поиск идентификатора по имени. Рассмотрим следующий фрагмент кода:
int id = Resources.getSystem().getIdentifier("btn_check_holo_light", "drawable", "android");
((CheckBox) findViewById(R.id.checkbox)).setButtonDrawable(id);
Первая строка фактически вернет идентификатор ресурса ресурса btn_check_holo_light
. Поскольку мы установили ранее, что это кнопка выбора, которая определяет внешний вид CheckBox
, мы можем установить его как "button drawable" в виджетах. Результатом является CheckBox
с появлением версии Holo.Light
, независимо от того, какую тему/стиль вы задали для приложения, активности или виджета в xml. Так как это устанавливает только кнопку drawable, вам нужно будет вручную изменить другой стиль; например в отношении внешнего вида текста.
Ниже скриншот, показывающий результат. Верхний флажок использует описанный выше метод (я вручную устанавливаю цвет текста в черный цвет в xml), а второй использует стиль Holo
по умолчанию на основе темы (не светлый, то есть).
Update2:
С помощью введения библиотеки поддержки v22.1.0 все стало намного проще! Цитата из примечаний к выпуску (мой акцент):
Lollipop добавил возможность перезаписывать тему при просмотре на уровне представления с помощью атрибута
android:theme
XML - невероятно полезного для таких вещей, как темные панели действий при активном освещении. Теперь AppCompat позволяет использоватьandroid:theme
для панелей инструментов (устаревшийapp:theme
, используемый ранее) и еще лучше, приноситandroid:theme
поддержку ко всем представлениям на устройствах API 11+.
Другими словами: теперь вы можете применить тему для каждого представления, что значительно облегчает решение исходной проблемы: просто укажите тему, которую вы хотите применить для соответствующего представления. То есть в контексте исходного вопроса, сравните результаты, приведенные ниже:
<CheckBox
...
android:theme="@android:style/Theme.Holo" />
<CheckBox
...
android:theme="@android:style/Theme.Holo.Light" />
Первый CheckBox
имеет стиль, как если бы использовался в темной теме, второй, как в легкой теме, независимо от фактической темы, установленной для вашей активности или приложения.
Конечно, вы больше не должны использовать тему Holo, но вместо этого используйте Material.