Sélecteur sur la couleur de fond de TextView

121

J'essaie de changer la couleur d'arrière-plan d'un TextViewwidget Android lorsque l'utilisateur le touche. J'ai créé un sélecteur à cet effet, qui est stocké dans res/color/selector.xmlet ressemble à peu près à ça:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:color="@color/semitransparent_white"
        />
    <item
        android:color="@color/transparent"
        />
</selector>

L' clickableattribut de TextViewest true, au cas où cela vous intéresse.

Lorsque j'attribue ce sélecteur à un TextViewas android:background="@color/selector", j'obtiens l'exception suivante au moment de l'exécution:

ERREUR / AndroidRuntime (13130): causée par: org.xmlpull.v1.XmlPullParserException: ligne de fichier XML binaire # 6: la balise nécessite un attribut 'drawable' ou une balise enfant définissant un dessinable

Quand je change l'attribut en drawable, cela fonctionne, mais le résultat est complètement faux car les ID semblent être interprétés comme des références d'image au lieu de références de couleur (comme le suggère le "drawable").

Ce qui me trouble, c'est que je peux définir une référence de couleur, par exemple "@ color / black", comme attribut d'arrière-plan directement. Cela fonctionne comme prévu. L'utilisation de sélecteurs ne fonctionne pas.

Je peux aussi utiliser le sélecteur comme le textColorsans problèmes.

Quelle est la bonne façon d'appliquer un sélecteur de couleur d'arrière-plan à un TextViewsous Android?

digitalbreed
la source
Une couleur peut être interprétée comme un dessin. En quoi le résultat est-il erroné exactement?
Romain Guy
Il ne montre pas la couleur mais une image de mes ressources dessinables comme arrière-plan.
digitalbreed
2
Ce qui précède devrait fonctionner, si vous utilisez android: drawable, pas android: color - au moins dans ce cas cela fonctionne pour moi: android: drawable = "@ color / my_custom_color". Mes couleurs sont définies dans values ​​/ colors.xml
AgentKnopf

Réponses:

226

Le problème ici est que vous ne pouvez pas définir la couleur d'arrière-plan à l'aide d'un sélecteur de couleur, vous avez besoin d'un sélecteur pouvant être dessiné . Ainsi, les changements nécessaires ressembleraient à ceci:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@drawable/selected_state" />
</selector>

Vous devrez également déplacer cette ressource vers le drawablerépertoire où cela aurait plus de sens car ce n'est pas un sélecteur de couleur en soi.

Ensuite, vous devrez créer le res/drawable/selected_state.xmlfichier comme ceci:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <solid android:color="@color/semitransparent_white" />
</shape>

et enfin, vous l'utiliseriez comme ceci:

android:background="@drawable/selector"

Remarque : la raison pour laquelle l'OP obtenait une ressource image dessinée est probablement parce qu'il a essayé de simplement référencer sa ressource qui était toujours dans le répertoire des couleurs, mais en utilisant @drawableainsi il s'est retrouvé avec une collision d'ID, sélectionnant la mauvaise ressource.

J'espère que cela peut encore aider quelqu'un même si l'OP a probablement, j'espère, résolu son problème maintenant.

Benoit Martin
la source
1
Merci, Benoit. Le problème a été résolu (je dois admettre que je ne me souviens plus comment exactement je l'ai fait à la fin) et le projet s'est terminé avec succès. J'apprécie que vous soyez revenu ici pour poster et aider les gens qui rencontrent le même problème à l'avenir, super esprit!
digitalbreed
Je ne peux pas faire fonctionner ça. J'essaie de l'appliquer à un bouton et cela définit l'arrière-plan sur la couleur par défaut du sélecteur, mais cela ne change pas pour la forme définie dans state_pressed. Que pourrais-je manquer? Je pourrais ouvrir une nouvelle question, juste au cas où vous pourriez m'indiquer la bonne direction.
Maragues le
@Maragues c'est difficile à dire sans voir de code. Je vous recommande d'ouvrir une nouvelle question et de publier le code correspondant afin que nous puissions déterminer ce qui pourrait ne pas être le bon. Vous pouvez également ajouter un commentaire à ce message avec un lien vers votre nouveau message.
Benoit Martin
9
Pourquoi ne pas simplement utiliser "drawable =" @ color / your_color "directement dans vos éléments de sélection à la place? Vous n'avez pas besoin de définir des formes ou tout autre fichier que ce soit, ayez simplement vos définitions de couleurs dans values ​​/ colors.xml (c'est toujours bon ne pas coder en dur les couleurs).
javaxian
Ca ne fonctionne pas. Il me montre la couleur différente des deux que j'ai déclarées en forme xml.
Er.Rohit Sharma
122

La solution de Benoit fonctionne, mais vous n'avez vraiment pas besoin d'engager des frais généraux pour dessiner une forme. Puisque les couleurs peuvent être dessinables, définissez simplement une couleur dans un fichier /res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="semitransparent_white">#77ffffff</color>
</resources>

Et puis utilisez comme tel dans votre sélecteur:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@color/semitransparent_white" />
</selector>
azdev
la source
Pour une raison quelconque, votre solution n'affiche pas la couleur mais une image aléatoire de mon dossier de ressources dessinables. J'ai essayé de nettoyer le projet / corriger les propriétés / réenregistrer / rouvrir l'éclipse car cela semble vraiment étrange, mais en vain. Bizarre.
Yahel
@Yahel Vous avez peut-être nommé la ressource color drawable de la même manière qu'un fichier dessinable réel?
Jona
@Jona: Non, mais le dessinable s'appelait background_application et la couleur dessinable s'appelait background_white_transparent. Les deux avaient des antécédents en eux ... J'ai vu sur un autre fil la même chose arriver à d'autres, alors j'ai classé cela comme l'un des nombreux bogues Android et j'ai réorganisé toute ma mise en page pour le contourner.
Yahel
@Yahel Mmm ... Eh bien, je vois ce problème mais dans mon cas, pas les mêmes noms de fichiers ... Consultez mes questions ici stackoverflow.com/questions/9004744/...
Jona
n'a pas réussi à le faire fonctionner, la réponse de Benoit Martin a bien fonctionné.
Emmanuel Touzery
83

Une solution encore plus simple à ce qui précède:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <color android:color="@color/semitransparent_white" />
    </item>
    <item>
        <color android:color="@color/transparent" />
    </item>
</selector>

Enregistrez-le dans le dossier pouvant être dessiné et vous êtes prêt à partir.

Jason Robinson
la source
1
Peut-être que cela fonctionne, mais n'est officiellement pas pris en charge (Android Studio le traite comme une erreur).
Blackhex
@Blackhex Strange. Fonctionne bien pour moi dans Eclipse. C'est probablement une erreur Lint, et si c'est le cas, vous devriez pouvoir la désactiver ou l'ignorer.
Jason Robinson
6
C'est ce que je considérerais comme la solution.
Lay González
<item android:state_pressed="true" android:color="@color/vantablack"/>ressemble sémantiquement identique à<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis
16

Même cela fonctionne.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/dim_orange_btn_pressed" />
    <item android:state_focused="true" android:drawable="@color/dim_orange_btn_pressed" />
    <item android:drawable="@android:color/white" />
</selector>

J'ai ajouté l' android:drawableattribut à chaque élément et leurs valeurs sont des couleurs.

Au fait, pourquoi disent-ils que colorc'est l'un des attributs de selector? Ils n'écrivent pas ce qui android:drawableest obligatoire.

Ressource de liste d'état des couleurs

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_window_focused=["true" | "false"] />
</selector>
Maksim Dmitriev
la source
L'attribut de couleur fonctionne lorsque vous définissez les couleurs de la vue de texte, mais pas avec l'arrière-plan, car les couleurs du fond sont agies comme ColorDrawable
Akhil Dad
La meilleure et la plus simple solution à mettre en œuvre de tout ce qui précède.
4gus71n
6

Pour qui cherche à le faire sans créer de secteur d'arrière-plan, ajoutez simplement ces lignes à la TextView

android:background="?android:attr/selectableItemBackground"
android:clickable="true"

Aussi pour le rendre sélectionnable, utilisez:

android:textIsSelectable="true"
Dasser Basyouni
la source