Как ссылаться на атрибуты стиля из прорисовки? - PullRequest
87 голосов
/ 07 ноября 2011

Я хочу иметь 2 выбираемые темы для моего приложения.Для этого я определил некоторые атрибуты, например:

 <attr format="color" name="item_background" />

Затем я создал обе темы, например:

  <style name="ThemeA">
     <item name="item_background">#123456</item>
 </style>

 <style name="ThemeB">
     <item name="item_background">#ABCDEF</item>
 </style>

Этот метод отлично работает, что позволяет мнесоздавать и изменять несколько тем легко.Проблема в том, что кажется, что его можно использовать только в представлениях, а не в Drawables .

Например, ссылка на значение из представления в макете работает:1012 *

Но делать то же самое в Drawable не получается:

 <shape android:shape="rectangle">
     <solid android:color="?item_background" />
 </shape>

При запуске приложения возникает ошибка:

    java.lang.UnsupportedOperationException: Can't convert to color: type=0x2

Если вместо ?item_background Iиспользуйте жестко заданный цвет, это работает, но это не позволяет мне использовать мои темы.Я также пытался ?attr:item_background, но то же самое происходит.

Как я мог это сделать?И почему это работает в представлениях, а не в Drawables?Я не могу найти это ограничение нигде в документации ...

Ответы [ 4 ]

152 голосов
/ 20 ноября 2012

По моему опыту невозможно ссылаться на атрибут в чертеже XML.
Для того, чтобы сделать вашу тему вам необходимо:

  • Создайте один xml-файл для каждой темы.
  • Включите нужный цвет в ваш рисунок, используя тег @color или формат #RGB.

Создайте атрибут для вашего рисования в attrs.xml .

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <!-- Attributes must be lowercase as we want to use them for drawables -->
   <attr name="my_drawable" format="reference" />
</resources>

Добавьте ваш Drawable в ваш theme.xml .

<style name="MyTheme" parent="@android:style/Theme.NoTitleBar">
   <item name="my_drawable">@drawable/my_drawable</item>
</style>

Ссылка вашего рисования в макете, используя ваш атрибут.

<TextView android:background="?my_drawable" />
15 голосов
/ 20 мая 2015

Начиная с lollipop (API 21) эта функция поддерживается, см. https://code.google.com/p/android/issues/detail?id=26251

Однако, если вы нацеливаетесь на устройства без леденца на палочке, не используйте его, так как он вылетит, вместо этого используйте обходной путь в принятом ответе.

4 голосов
/ 11 декабря 2016

Хотя на атрибуты pre-Lollipop можно ссылаться на атрибуты стиля из элементов рисования, но это возможно для списков состояний цвета.Вы можете использовать AppCompatResources.getColorStateList (Context context, int resId) метод из библиотеки поддержки Android.Недостатком является то, что вам придется устанавливать эти списки состояний цвета программно.

Вот очень простой пример.

color / my_color_state.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_checked="true" android:color="?colorControlActivated" />
  <item android:color="?colorControlNormal" />
</selector>

Виджет, которому нужен список состояний цвета:

<RadioButton
  android:id="@+id/radio_button"
  android:text="My Radio" />

И самое важное:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_color_state);    
RadioButton r = (RadioButton) findViewById(R.id.radio_button);
r.setTextColor(csl);

Ну, не самый элегантный или самый короткийДа, но это то, что делает библиотека поддержки Android, чтобы она работала на более старых версиях (до Lollipop) Android.

К сожалению, аналогичный метод для рисования не работает со стилематрибуты.

0 голосов
/ 11 мая 2016

Как сказал @marmor, теперь это поддерживается в API 21. Но для тех из нас, кому необходимо поддерживать устаревшие версии Android, вы можете использовать эту функцию.Используя библиотеку поддержки v7, вы все равно можете использовать ее в приложениях с минимальным уровнем SDK вплоть до 7.

В AppCompatImageView в библиотеке поддержки Android v7 реализована эта функция без ошибок.Просто замените ваше использование ImageView на AppCompatImageView.

...