Par exemple, le bouton par défaut a les dépendances suivantes entre ses états et les images d'arrière-plan:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
Comment puis-je définir mon propre état personnalisé (smth like android:state_custom
), afin que je puisse l'utiliser pour modifier dynamiquement l'apparence visuelle de mon bouton?
Réponses:
La solution indiquée par @ (Ted Hopp) fonctionne, mais nécessite une petite correction: dans le sélecteur, les états de l'élément ont besoin d'un préfixe "app:", sinon le gonfleur ne reconnaîtra pas correctement l'espace de noms, et échouera silencieusement; du moins c'est ce qui m'arrive.
Permettez-moi de vous rapporter ici toute la solution, avec quelques détails supplémentaires:
Commencez par créer le fichier "res / values / attrs.xml":
Définissez ensuite votre classe personnalisée. Par exemple, il peut s'agir d'une classe "FoodButton", dérivée de la classe "Button". Vous devrez implémenter un constructeur; implémentez celui-ci, qui semble être celui utilisé par le gonfleur:
En plus de la classe dérivée:
En outre, vos variables d'état:
Et quelques setters:
Remplacez ensuite la fonction "onCreateDrawableState":
Enfin, la pièce la plus délicate de ce puzzle; le sélecteur définissant le StateListDrawable que vous utiliserez comme arrière-plan de votre widget. Il s'agit du fichier "res / drawable / food_button.xml":
Notez le préfixe "app:", alors qu'avec les états Android standard, vous auriez utilisé le préfixe "android:". L'espace de noms XML est crucial pour une interprétation correcte par le gonfleur et dépend du type de projet dans lequel vous ajoutez des attributs. S'il s'agit d'une application, remplacez com.mydomain.mypackage par le nom réel du package de votre application (nom de l'application exclu). S'il s'agit d'une bibliothèque, vous devez utiliser "http://schemas.android.com/apk/res-auto" (et utiliser Tools R17 ou version ultérieure) ou vous obtiendrez des erreurs d'exécution.
Quelques notes:
Il semble que vous n'ayez pas besoin d'appeler la fonction "refreshDrawableState", au moins la solution fonctionne bien telle quelle, dans mon cas
Afin d'utiliser votre classe personnalisée dans un fichier xml de mise en page, vous devrez spécifier le nom complet (par exemple com.mydomain.mypackage.FoodButton)
Vous pouvez comme weel mélanger des états standard (par exemple android: pressé, android: activé, android: sélectionné) avec des états personnalisés, afin de représenter des combinaisons d'états plus compliquées
la source
refreshDrawableState
est vraiment important. Je ne sais pas vraiment quand c'est vraiment nécessaire. Mais dans mon cas, il était nécessaire lors de la définition de l'état par programme. Je suppose qu'il est peut-être appelé automatiquement à partir de la classe View dans le onTouchEvent. Je ferais mieux de l'ajouter dans la méthode setSelected.boolean
? Ou les sélecteurs fonctionnent-ils uniquement sur des booléens?Ce fil montre comment ajouter des états personnalisés aux boutons et autres. (Si vous ne pouvez pas voir les nouveaux groupes Google dans votre navigateur, il y a une copie du fil ici .)
la source
N'oubliez pas d'appeler
refreshDrawableState
dans le fil de l'interface utilisateur:Il m'a fallu beaucoup de temps pour comprendre pourquoi mon bouton ne change pas d'état même si tout semble correct.
la source