Jak odwoływać się do atrybutów stylu z drawable?

Chcę mieć 2 wybrane motywy dla mojej aplikacji. W tym celu zdefiniowałem kilka atrybutów, takich jak:

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

Potem stworzyłem oba tematy, tak:

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

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

Ta metoda działa świetnie, pozwalając mi łatwo tworzyć i modyfikować kilka tematów. Problem polega na tym, że wydaje się, że może być używany tylko w widokach, a nie w Drawables .

Na przykład odwołanie się do wartości z widoku wewnątrz układu działa:

 <TextView android:background="?item_background" />

Ale robiąc to samo w Drawable nie:

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

Dostaję ten błąd podczas uruchamiania aplikacji:

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

Jeśli zamiast ?item_background używam zakodowanego na twardo koloru, działa, ale to nie pozwala mi używać moich motywów. Próbowałem też ?attr:item_background, ale dzieje się tak samo.

Jak mogłem to zrobić? I dlaczego działa w widokach, a nie w Drawables? Nie mogę znaleźć tego ograniczenia nigdzie w dokumentacji ...
Author: L. G., 2011-11-07

4 answers

Z mojego doświadczenia nie jest możliwe odniesienie do atrybutu w XML drawable.
Aby stworzyć swój motyw musisz:

  • Utwórz jeden XML drawable dla każdego motywu.
  • Dodaj do siebie potrzebny kolor, który można narysować bezpośrednio za pomocą tagu @color lub formatu #RGB.

Stwórz atrybut dla swojego drawable w 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>

Dodaj swój rysunek do tematu .xml .

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

Reference your możliwość rysowania w układzie za pomocą atrybutu.

<TextView android:background="?my_drawable" />
 142
Author: L. G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-08 13:56:21

Począwszy od lollipop (API 21) Ta funkcja jest obsługiwana, zobacz https://code.google.com/p/android/issues/detail?id=26251

Jeśli jednak celujesz w urządzenia bez lizaka, nie używaj go, ponieważ ulegnie awarii, zamiast tego użyj obejścia w zaakceptowanej odpowiedzi.

 15
Author: marmor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-20 13:47:55

Chociaż nie jest możliwe odwoływanie się do atrybutów stylu z drawables na urządzeniach pre-Lollipop , ale jest to możliwe dla list stanu kolorów. Możesz użyć AppCompatResources.getColorStateList (context context, int resId) metoda z biblioteki wsparcia dla Androida. Minusem jest to, że będziesz musiał programowo ustawić te listy stanu kolorów.

Oto bardzo podstawowy przykład.

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>

Widżet, który potrzebuje koloru lista państw:

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

I najważniejsze:

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

Cóż, nie jest to najbardziej elegancki lub najkrótszy sposób, ale to jest to, co Android Support Library robi, aby działać na starszych wersjach (pre-Lollipop) Androida.

Niestety, podobna metoda nie działa z atrybutami stylu.

 4
Author: rubo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-11 15:07:33

Jak stwierdził @ marmor, jest to teraz obsługiwane przez API 21. Ale dla tych, którzy muszą obsługiwać starsze wersje Androida, możesz skorzystać z tej funkcji. Korzystając z biblioteki wsparcia v7, możesz nadal używać jej w aplikacjach z minimalnym poziomem SDK aż do 7.

AppCompatImageView w Bibliotece wsparcia dla Androida v7 ma wolną od błędów implementację tej funkcji. Po prostu Zamień swoje użycie ImageView na AppCompatImageView.

 0
Author: Benjamin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 14:50:28