115 votes

Remplacer les images de sélecteur par programme

J'ai un ImageView qui a une ressource d'image dessinable définie à un sélecteur. Comment puis-je accéder par programmation au sélecteur et modifier les images de l'état mis en surbrillance et non mis en surbrillance?

Voici un code de sélecteur:

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iconSelector">
  <!-- pressed -->
  <item android:state_pressed="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- focused -->
  <item android:state_focused="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- default -->
  <item android:drawable="@drawable/btn_icon" />
</selector>
 

Je veux pouvoir remplacer btn_icon_hl et btn_icon par d'autres images.

244voto

kcoppock Points 57219

Pour autant que j'ai pu trouver (j'ai essayé de faire quelque chose de similaire moi-même), il n'y a aucun moyen de modifier un seul état après que StateListDrawable a déjà été défini. Vous pouvez cependant définir un nouveau code via:

 StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
    getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {android.R.attr.state_focused},
    getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
    getResources().getDrawable(R.drawable.normal));
imageView.setImageDrawable(states);
 

Et vous pouvez simplement en garder deux sous la main ou en créer un différent selon vos besoins.

6voto

Emile Points 4660

J'ai eu le même problème et est allé plus loin pour le résoudre. Le seul problème, toutefois, est que vous ne pouvez pas spécifier les NavStateListDrawable en xml, donc vous devez définir l'arrière-plan de votre élément de l'INTERFACE utilisateur à l'aide de code. Le onStateChange méthode doit alors être changé pour s'assurer que chaque fois que le niveau de la principale drawable est changé, que vous pouvez également mettre à jour le niveau de l'enfant niveau de la liste.

Lors de la construction de la NavStateListDrawable vous avez à passer dans le niveau de l'icône que vous souhaitez afficher.

public class NavStateListDrawable extends StateListDrawable {

    private int level;

    public NavStateListDrawable(Context context, int level) {

        this.level = level;
        //int stateChecked = android.R.attr.state_checked;
        int stateFocused = android.R.attr.state_focused;
        int statePressed = android.R.attr.state_pressed;
        int stateSelected = android.R.attr.state_selected;

        addState(new int[]{ stateSelected      }, context.getResources().getDrawable(R.drawable.nav_btn_pressed));
        addState(new int[]{ statePressed      }, context.getResources().getDrawable(R.drawable.nav_btn_selected));
        addState(new int[]{ stateFocused      }, context.getResources().getDrawable(R.drawable.nav_btn_focused));

        addState(new int[]{-stateFocused, -statePressed, -stateSelected}, context.getResources().getDrawable(R.drawable.nav_btn_default));


    }

    @Override
    protected boolean onStateChange(int[] stateSet) {

        boolean nowstate = super.onStateChange(stateSet);

        try{
            LayerDrawable defaultDrawable = (LayerDrawable)this.getCurrent();


            LevelListDrawable bar2 =  (LevelListDrawable)defaultDrawable.findDrawableByLayerId(R.id.nav_icons);
            bar2.setLevel(level);
        }catch(Exception exception)
        {

        }

        return nowstate;
    }
}

Pour tous les différents boutons de navigation drawable états j'ai quelque chose comme ce qui suit.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

   <item android:drawable="@drawable/top_bar_default" >

   </item>

    <item android:id="@+id/nav_icons" android:bottom="0dip">
        <level-list xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:maxLevel="0" >
                <bitmap
                    android:src="@drawable/top_bar_icon_back"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="1" >
                <bitmap
                    android:src="@drawable/top_bar_icon_nav"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="2" >
                <bitmap
                    android:src="@drawable/top_bar_icon_settings"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="3" >
                <bitmap
                    android:src="@drawable/top_bar_icon_search"
                    android:gravity="center" />
            </item>
        </level-list>

    </item>

</layer-list>

J'allais le poster cela comme une question et la réponse, mais vu que vous avez posé la question, ici vous allez. Remarque, cela vous fait gagner un enfer de beaucoup de xml fichier de définitions. je suis allé vers le bas d'environ 50-100 définitions xml vers le bas à environ 4!.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X