Je souhaite avoir 2 thèmes sélectionnables pour mon application. Pour ce faire, j'ai défini quelques attributs, comme ceci:
<attr format="color" name="item_background" />
Ensuite, j'ai créé les deux thèmes, comme ceci:
<style name="ThemeA">
<item name="item_background">#123456</item>
</style>
<style name="ThemeB">
<item name="item_background">#ABCDEF</item>
</style>
Cette méthode fonctionne très bien, me permettant de créer et de modifier facilement plusieurs thèmes. Le problème est qu'il semble qu'il ne puisse être utilisé que dans Views, et non dans Drawables .
Par exemple, le référencement d'une valeur à partir d'une vue à l'intérieur d'une mise en page fonctionne:
<TextView android:background="?item_background" />
Mais faire la même chose dans un Drawable ne permet pas:
<shape android:shape="rectangle">
<solid android:color="?item_background" />
</shape>
J'obtiens cette erreur lors de l'exécution de l'application:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
Si au lieu d' ?item_background
utiliser une couleur codée en dur, cela fonctionne, mais cela ne me permet pas d'utiliser mes thèmes. J'ai aussi essayé ?attr:item_background
, mais la même chose se produit.
Comment pourrais-je faire ça? Et pourquoi cela fonctionne-t-il dans Views mais pas dans Drawables? Je ne trouve cette limitation nulle part dans la documentation ...
Réponses:
D'après mon expérience, il n'est pas possible de référencer un attribut dans un dessin XML.
Pour créer votre thème, vous devez:
Incluez la couleur nécessaire dans votre dessin directement avec la
@color
balise ou le format #RGB.Créez un attribut pour votre dessinable dans attrs.xml .
Ajoutez votre dessinable à votre theme.xml .
Faites référence à votre dessinable dans votre mise en page en utilisant votre attribut.
la source
À partir de
lollipop
(API 21), cette fonctionnalité est prise en charge, voir https://code.google.com/p/android/issues/detail?id=26251Cependant, si vous ciblez des appareils sans sucette, ne l'utilisez pas, car cela plantera, utilisez plutôt la solution de contournement dans la réponse acceptée.
la source
Bien qu'il ne soit pas possible de référencer des attributs de style à partir de dessinables sur des appareils pré-Lollipop , mais c'est possible pour les listes d'état de couleur. Vous pouvez utiliser la méthode AppCompatResources.getColorStateList (Context context, int resId) de la bibliothèque de support Android. L'inconvénient est que vous devrez définir ces listes d'états de couleur par programmation.
Voici un exemple très basique.
color / my_color_state.xml
Un widget qui a besoin d'une liste d'état des couleurs:
Et le plus important:
Eh bien, ce n'est pas le moyen le plus élégant ou le plus court, mais c'est ce que fait la bibliothèque de support Android pour la faire fonctionner sur les anciennes versions (pré-Lollipop) d'Android.
Malheureusement, la méthode similaire pour les drawables ne fonctionne pas avec les attributs de style.
la source
J'ai répondu à la même question sur https://stackoverflow.com/a/59467269/3841352 mais je la posterai également ici:
J'ai rencontré le même problème et à partir de 2019, il n'a pas été résolu, vous ne pouvez donc pas avoir un attribut référencé dans un sélecteur comme dessinable. Je vais partager la solution que j'ai obtenue pour le problème car je ne la vois pas publiée ici. Je l'ai trouvé dans le dernier commentaire du rapport de bogue .
La solution de contournement consiste essentiellement à créer une ressource dessinable qui sera celle faisant référence à la valeur d'attribut.
Pour illustrer votre cas, la solution serait au lieu de:
vous remplaceriez le? attr / * pour une ressource dessinable:
Les drawables seraient définis comme:
drawable / colorPrimaryDrawable
drawable / colorPrimaryDarkDrawable
J'espère que ça aide!!
la source
Comme @marmor l'a indiqué, cela est désormais pris en charge sur l'API 21. Mais pour ceux qui ont besoin de prendre en charge les anciennes versions d'Android, vous pouvez utiliser cette fonctionnalité. En utilisant la bibliothèque de support v7, vous pouvez toujours l'utiliser sur des applications avec un niveau minimum de SDK jusqu'à 7.
La
AppCompatImageView
bibliothèque de support Android v7 a une implémentation sans bogue de cette fonctionnalité. Remplacez simplement vos utilisations deImageView
parAppCompatImageView
.la source