Android: spécifiez deux images différentes pour le bouton bascule à l'aide de XML

100

J'essaie de remplacer l' ToggleButtonapparence par défaut . Voici le XML qui définit le ToggleButton:

<ToggleButton android:id="@+id/FollowAndCenterButton"
        android:layout_width="30px"
        android:layout_height="30px"
        android:textOn="" android:textOff="" android:layout_alignParentLeft="true"
        android:layout_marginLeft="5px"
        android:layout_marginTop="5px" android:background="@drawable/locate_me"/>

Maintenant, nous avons deux icônes 30 x 30 que nous voulons utiliser pour les états cliqués / non cliqués. À l'heure actuelle, nous avons du code qui modifie par programme l'icône d'arrière-plan en fonction de l'état:

centeredOnLocation.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            if (centeredOnLocation.isChecked()) {
                centeredOnLocation.setBackgroundDrawable(getResources().getDrawable(R.drawable.locate_me_on));
            } else {
                centeredOnLocation.setBackgroundDrawable(getResources().getDrawable(R.drawable.locate_me));
            }
        }
});

De toute évidence, je cherche une meilleure façon de faire cela. J'ai essayé de créer un sélecteur pour l'image d'arrière-plan, qui basculerait automatiquement entre les états:

 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/locate_me" /> <!-- default -->
 <item android:state_checked="true"
       android:drawable="@drawable/locate_me_on" /> <!-- pressed -->
 <item android:state_checked="false"
       android:drawable="@drawable/locate_me" /> <!-- unchecked -->

Mais cela ne fonctionne pas; en lisant l' ToggleButtonAPI ( http://developer.android.com/reference/android/widget/ToggleButton.html ), il semble que les seuls attributs xml hérités sont

    XML Attributes
Attribute Name  Related Method  Description
android:disabledAlpha       The alpha to apply to the indicator when disabled. 
android:textOff         The text for the button when it is not checked. 
android:textOn      The text for the button when it is checked. 

Il ne semble pas y avoir l'attribut android: state_checked, bien que la classe ait la méthode isChecked()et setChecked().

Alors, y a-t-il un moyen de faire ce que je veux dans XML, ou suis-je coincé avec ma solution de contournement désordonnée?

I82Much
la source
Notez que si vous n'utilisez pas de texte, je pense qu'il vaut peut-être mieux l'utiliser CompoundButton.
Timmmm
1
Ne tenez pas compte de cela; CompoundButtonest abstrait!
Timmmm

Réponses:

159

Votre code est correct. Cependant, le bouton bascule affichera le premier élément de votre sélecteur auquel il correspond, donc la valeur par défaut doit venir en dernier. Disposez les articles de la manière suivante pour vous assurer qu'ils seront tous utilisés:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:state_pressed="true" /> //currently pressed turning the toggle on
    <item android:state_pressed="true" /> //currently pressed turning the toggle off
    <item android:state_checked="true" /> //not pressed default checked state
    <item /> //default non-pressed non-checked
</selector>
m_vitaly
la source
3
Cela est parfaitement logique; Je n'ai jamais fait le lien entre les instructions selector et switch.
I82Much
Vous avez fait ma journée ... J'ai eu des problèmes avec le bouton, la case à cocher, puis j'ai également essayé le bouton radio, enfin ce message a été utile. Merci beaucoup Vitaly Polonetsky et I82Much
David Prun
8
la documentation dit quelque part qu'elle lit du haut, en s'arrêtant au premier état dont les conditions sont toutes remplies, donc si la valeur par défaut est en haut, il ne dépassera jamais ce dessinable.
Travis
1
@ I82Much a switchsélectionnerait toujours le "bon" quel que soit l'ordre, cela se comporte plus comme un long if-elseif-elseif-elseavec des conditions comme state_x == true && state_y == false && state_z = true.
TWiStErRob