Comment ajouter un bouton personnalisé état
Par exemple, le bouton par défaut est la suivante dépendances entre ses membres 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 (qch comme android:state_custom
), alors je pourrais l'utiliser pour modifier dynamiquement mon bouton aspect visuel?
- Je voulais extra-unis pour un EditText vue de déterminer quand les deux mots de passe des boîtes de match pour montrer un peu le coche.
Vous devez vous connecter pour publier un commentaire.
La solution indiquée par @Ted(Hopp) fonctionne, mais a besoin d'une petite correction: dans le sélecteur, l'article états besoin d'une application":" prefix, sinon le inflater refuse de reconnaître l'espace de noms correctement, et échoue silencieusement; au moins, c'est ce qui m'arrive.
Permettez-moi de signaler ici l'ensemble de la solution, avec un peu plus de détails:
Tout d'abord, créez un fichier "res/values/attrs.xml":
Ensuite définir votre classe personnalisée. Par exemple, il peut être une classe "FoodButton", dérivée de la classe "Bouton". Vous aurez à mettre en œuvre un constructeur; mise en place de celui-ci, qui semble être celle qui est utilisée par le inflater:
Sur le dessus de la classe dérivée:
Aussi, vos variables d'état:
Et un couple de setters:
Puis remplacer la fonction "onCreateDrawableState":
Enfin, les plus délicates pièces de ce puzzle; le sélecteur de la définition de la StateListDrawable que vous allez utiliser comme arrière-plan pour votre widget. C'est le fichier "res/drawable/food_button.xml":
Avis de l'application":" préfixe, alors qu'avec android standard états-unis, il aurait utilisé le préfixe "android:". L'espace de noms XML est crucial pour une interprétation correcte par le inflater et dépend du type de projet dans lequel vous ajoutez des attributs. Si c'est une application, remplacer com.mydomain.mypackage avec le nom du package de votre application (nom de l'application exclus). Si c'est une bibliothèque, vous devez utiliser "http://schemas.android.com/apk/res-auto" (et être à l'aide d'Outils R17 ou plus tard) ou vous obtiendrez des erreurs d'exécution.
Un couple de notes:
Il semble que vous n'avez pas besoin d'appeler le "refreshDrawableState" de la fonction, au moins la solution fonctionne bien comme c'est, dans mon cas
L'utilisation de votre classe personnalisée dans une mise en page fichier xml, vous devez spécifier le nom complet (par exemple, com.mydomain.mypackage.FoodButton)
Vous pouvez ainsi mélanger-up standard des états (p. ex. android:pressé, android:activé, android:sélectionné) personnalisée avec des états, afin de représenter plus compliqué état combinaisons
refreshDrawableState
est certainement important. Je ne suis pas absolument sûr que quand c'est vraiment nécessaire. Mais dans mon cas, il a été nécessaire lors de la configuration de l'état de la programmation. Je suppose que c'est peut-être appelée à partir de la classe de la Vue automatiquement dans le onTouchEvent. Je ferais mieux de l'ajouter dans la méthode setSelected.duplicateParentState="true"
? J'ai une ligne deImageViews
qui ne sont pas individuellement peut recevoir le focus et l'utilisation de l'état parent, mais j'aimerais ajouter un peu de repère visuel à l'un d'eux à un moment.setBaked()
ousetFried()
il n'appelle pas automatiquement leonCreateDrawableState()
de sorte que vous devez appelerrefreshDrawableState()
.Si vous modifiez l'état natif de bouton à droite après le nouveau changement d'état, vous n'avez pas à actualiser depuisonCreateDrawableState()
sera appelé par les indigènes de changement d'état.boolean
? Ou sont les sélecteurs d'exploitation uniquement sur les booléens?declare-styleable
n'est pas vraiment nécessaire, même s'il continue de générer de corrigerattr
ressources. Donc, il vous suffit de définir vosattr
comme est.xmlns:
dans le sélecteur. Il doit toujours êtrexmlns:myapp="http://schemas.android.com/apk/res/com.example.asd"
avec res . Bénéficiez également de package n'est pas le nom de la manifest fichier mais plutôt que de vous app.construire identificateur applicationidxmlns:app="http://schemas.android.com/apk/res-auto"
partout, pas seulement dans les bibliothèques. stackoverflow.com/a/30620868/6182136Ce fil montre comment ajouter des membres à boutons et autres. (Si vous ne pouvez pas voir la nouvelle version de Google groupes dans votre navigateur, il y a une copie du fil ici.)
S'il vous plaît ne pas oublier d'appeler
refreshDrawableState
dans les thread de l'INTERFACE utilisateur:Il a pris beaucoup de mon temps à comprendre pourquoi mon bouton ne change pas son état, même si tout semble correct.