¿Cómo hacer referencia a los atributos de estilo de un dibujable?

Quiero tener 2 temas seleccionables para mi aplicación. Para hacer eso, definí algunos atributos, como este:

 

Entonces, creé ambos temas, así:

   #123456   #ABCDEF  

Este método funciona muy bien, lo que me permite crear y modificar varios temas fácilmente. El problema es que parece que solo se puede usar en Vistas, y no en Dratables .

Por ejemplo, hacer referencia a un valor de una Vista dentro de un diseño funciona:

   

Pero hacer lo mismo en un Drawable no:

     

Me sale este error al ejecutar la aplicación:

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

Si en lugar de ?item_background utilizo un color codificado, funciona, pero eso no me permite usar mis temas. También probé ?attr:item_background , pero sucede lo mismo.

¿Cómo podría hacer esto? ¿Y por qué funciona en Views pero no en Drawables? No puedo encontrar esta limitación en ningún lugar de la documentación …

En mi experiencia, no es posible hacer referencia a un atributo en un xml drawable.
Para hacer tu tema necesitas:

  • Crea un xml dibujable por tema.
  • Incluya el color necesario en su dibujo directamente con la etiqueta @color o el formato #RGB.

Haz un atributo para tu dibujo en attrs.xml .

      

Agregue su dibujable a su theme.xml .

  

Haga referencia a su dibujo en su diseño utilizando su atributo.

  

Comenzando con lollipop (API 21) esta característica es compatible, consulte https://code.google.com/p/android/issues/detail?id=26251

Sin embargo, si está orientando dispositivos sin lollipop, no lo use, ya que se bloqueará; en su lugar, use la solución en la respuesta aceptada.

Aunque no es posible hacer referencia a los atributos de estilo de los objetos dibujables en dispositivos anteriores a Lollipop , sí es posible utilizar listas de estado de color. Puede usar el método AppCompatResources.getColorStateList (Context context, int resId) de la Biblioteca de soporte de Android. El inconveniente es que tendrá que establecer esas listas de estado de color mediante progtwigción.

Aquí hay un ejemplo muy básico.

color / my_color_state.xml

     

Un widget que necesita una lista de estado de color:

  

Y lo mas importante:

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

Bueno, no de la manera más elegante o más corta, pero esto es lo que hace la Biblioteca de soporte de Android para que funcione en versiones anteriores (anteriores a Lollipop) de Android.

Desafortunadamente, el método similar para dibujables no funciona con los atributos de estilo.

Como @marmor declaró que esto ahora es compatible con API 21. Pero para aquellos que necesiten soportar versiones heredadas de Android, puedes usar esta característica. Con la biblioteca de soporte de v7, puede usarlo en aplicaciones con un nivel mínimo de SDK hasta 7.

AppCompatImageView en la Biblioteca de soporte de Android v7 tiene una implementación libre de errores de esta característica. Simplemente reemplace sus usos de ImageView con AppCompatImageView .