La solution indiquée par @(Ted Hopp) fonctionne, mais a besoin d'une petite correction : dans le sélecteur, les états des éléments ont besoin d'un préfixe "app :", sinon l'inflater ne reconnaîtra pas correctement l'espace de noms et échouera silencieusement ; du moins c'est ce qui m'arrive.
Permettez-moi de rapporter ici l'ensemble de la solution, avec quelques détails supplémentaires :
Tout d'abord, créez le fichier "res/values/attrs.xml" :
Ensuite, définissez votre classe personnalisée. Par exemple, cela peut être 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 l'inflater :
public FoodButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
En haut de la classe dérivée :
private static final int[] STATE_FRIED = {R.attr.state_fried};
private static final int[] STATE_BAKED = {R.attr.state_baked};
Aussi, vos variables d'état :
private boolean mIsFried = false;
private boolean mIsBaked = false;
Et quelques setters :
public void setFried(boolean isFried) {mIsFried = isFried;}
public void setBaked(boolean isBaked) {mIsBaked = isBaked;}
Ensuite, remplacez la fonction "onCreateDrawableState" :
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
if (mIsFried) {
mergeDrawableStates(drawableState, STATE_FRIED);
}
if (mIsBaked) {
mergeDrawableStates(drawableState, STATE_BAKED);
}
return drawableState;
}
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 pour votre widget. C'est le fichier "res/drawable/food_button.xml" :
Remarquez 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 l'inflater 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 du package réel 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 ultérieur) ou vous obtiendrez des erreurs d'exécution.
Quelques notes :
-
Il semble que vous n'ayez pas besoin d'appeler la fonction "refreshDrawableState", du moins la solution fonctionne bien telle quelle, dans mon cas
-
Pour utiliser votre classe personnalisée dans un fichier de mise en page xml, vous devrez spécifier le nom entièrement qualifié (par exemple com.mydomain.mypackage.FoodButton)
-
Vous pouvez également mélanger les états standard (par exemple android:pressed, android:enabled, android:selected) avec des états personnalisés, afin de représenter des combinaisons d'états plus complexes
0 votes
Je voulais des états supplémentaires pour une vue EditText pour déterminer quand deux cases de mot de passe correspondent pour afficher un petit coche.