Quiero tener 2 temas seleccionables para mi aplicación. Para hacer eso, definí algunos atributos, como este:
<attr format="color" name="item_background" />
Luego, creé ambos temas, así:
<style name="ThemeA">
<item name="item_background">#123456</item>
</style>
<style name="ThemeB">
<item name="item_background">#ABCDEF</item>
</style>
Este método funciona muy bien, permitiéndome crear y modificar varios temas fácilmente. El problema es que parece que solo se puede usar en Views y no en Drawables .
Por ejemplo, hacer referencia a un valor de una Vista dentro de un diseño funciona:
<TextView android:background="?item_background" />
Pero hacer lo mismo en un Drawable no:
<shape android:shape="rectangle">
<solid android:color="?item_background" />
</shape>
Recibo este error al ejecutar la aplicación:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
Si en lugar de ?item_background
usar un color codificado, funciona, pero eso no me permite usar mis temas. También lo intenté ?attr:item_background
, pero pasa 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 ninguna parte de la documentación ...
Respuestas:
En mi experiencia, no es posible hacer referencia a un atributo en un elemento de diseño XML.
Para crear tu tema necesitas:
Incluya el color necesario en su dibujo directamente con la
@color
etiqueta o el formato #RGB.Cree un atributo para su elemento de dibujo en attrs.xml .
Agregue su elemento de dibujo a su theme.xml .
Haga referencia a su dibujable en su diseño usando su atributo.
fuente
A partir de
lollipop
(API 21), esta función es compatible, consulte https://code.google.com/p/android/issues/detail?id=26251Sin embargo, si está apuntando a dispositivos sin piruleta, no lo use, ya que se bloqueará, use la solución alternativa en la respuesta aceptada.
fuente
Aunque no es posible hacer referencia a atributos de estilo de elementos de diseño en dispositivos anteriores a Lollipop , es posible para listas de estado de color. Puede usar el método AppCompatResources.getColorStateList (Context context, int resId) de la biblioteca de compatibilidad de Android. La desventaja es que tendrá que configurar esas listas de estado de color mediante programación.
He aquí un ejemplo muy básico.
color / my_color_state.xml
Un widget que necesita una lista de estado de color:
Y lo mas importante:
Bueno, no es la forma 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 los elementos de diseño no funciona con los atributos de estilo.
fuente
Respondí la misma pregunta en https://stackoverflow.com/a/59467269/3841352 pero también la publicaré aquí:
Encontré el mismo problema y, a partir de 2019, no se ha resuelto, por lo que no se puede hacer referencia a un atributo en un selector como dibujable. Compartiré la solución que obtuve para el problema, ya que no la veo publicada aquí. Lo encontré en el último comentario del informe de errores .
La solución es básicamente crear un recurso dibujable que será el que se refiera al valor del atributo.
Para ilustrar su caso, la solución sería en lugar de:
reemplazaría el? attr / * por un recurso dibujable:
Los dibujables se definirían como:
dibujable / colorPrimaryDrawable
drawable / colorPrimaryDarkDrawable
¡¡Espero eso ayude!!
fuente
Como dijo @marmor, esto ahora es compatible con API 21. Pero para aquellos que necesitamos admitir versiones heredadas de Android, pueden usar esta función. Con la biblioteca de soporte v7, aún puede usarla en aplicaciones con un nivel mínimo de SDK hasta 7.
La
AppCompatImageView
biblioteca de soporte de Android v7 tiene una implementación sin errores de esta función. Simplemente reemplace sus usos deImageView
conAppCompatImageView
.fuente