Comment définir par programme drawableLeft sur le bouton Android?


442

Je crée dynamiquement des boutons. Je les ai d'abord stylisés en utilisant XML, et j'essaie de prendre le XML ci-dessous et de le rendre programmatique.

<Button
    android:id="@+id/buttonIdDoesntMatter"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:text="buttonName"
    android:drawableLeft="@drawable/imageWillChange"
    android:onClick="listener"
    android:layout_width="fill_parent">
</Button>

C'est ce que j'ai jusqu'à présent. Je peux tout faire sauf le tirable.

linear = (LinearLayout) findViewById(R.id.LinearView);
Button button = new Button(this);
button.setText("Button");
button.setOnClickListener(listener);
button.setLayoutParams(
    new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,         
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT
    )
);      

linear.addView(button);

Réponses:


1055

Vous pouvez utiliser la setCompoundDrawablesméthode pour ce faire. Voir l'exemple ici . Je l'ai utilisé sans utiliser le setBoundset cela a fonctionné. Vous pouvez essayer de toute façon.

MISE À JOUR : Copier le code ici au cas où le lien descend

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
img.setBounds(0, 0, 60, 60);
txtVw.setCompoundDrawables(img, null, null, null);

ou

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
txtVw.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);

ou

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

@Varun, @Tigger: J'ai un problème avec ceci: mon gestionnaire de fichiers affiche les dossiers dans une liste avec des vues de texte et une icône de dossier en tant que drawableLeft. J'ai essayé vos suggestions ici pour définir une "icône interdite" lorsque vous cliquez dans un dossier sans autorisations de lecture, et cela fonctionne. Toutefois, lorsque vous changez de dossier et que l'adaptateur est rechargé, l'icône interdite persiste (c'est-à-dire qu'elle n'est drawableLeftpas redessinée). Savez-vous comment postuler notifyDataSetChangedaussi pour le drawableLeft, sans faire de boucle? Merci!
Luis A. Florit

@ LuisA.Florit Il semble que vous ayez une question liée au redessin d'un Listviewélément lorsque les données changent - ce qui n'a pas vraiment de rapport avec cette question ou réponse. Je vous suggère de poster une question au lieu d'un commentaire.
Tigger

@Tigger: Eh bien, j'ai également rétabli l'icône en utilisant votre astuce et une boucle sur les répertoires interdits. Peut-être que c'est mieux que de redessiner tous les éléments ListView ... Merci quand même!
Luis A. Florit

3
Je vois quelque chose d'étrange dans mon application. Le setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )ne fonctionne pas, si je définis le drawableRight dans le layout.xml. Si je mets l'icône d'origine à l'intérieur onCreate(), le changement fonctionne. Pourrait-il être lié à l'API 19?
injecteur

L'exemple de lien ne s'ouvre pas. Existe-t-il un lien alternatif?
Yogesh Umesh Vaity

100

Vous pouvez aussi l'essayer aussi

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4
R.drawable.smiley devrait être à la place du premier 0 (le premier paramètre) et non du dernier car la définition de cette méthode est: {public void setCompoundDrawablesWithIntrinsicBounds (int gauche, int haut, int droite, int bas)}
arniotaki

Comment puis-je également ajouter un rembourrage autour de cela? Il n'y a pas beaucoup de remplissage entre le dessinable et le texte de cette façon.
AdamMc331

16

Kotlin Version

Utilisez l'extrait ci-dessous pour ajouter une gauche dessinable au bouton:

val drawable = ContextCompat.getDrawable(context, R.drawable.ic_favorite_white_16dp)
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

.

Important Point in Using Android Vector Drawable

Lorsque vous utilisez un vecteur Android dessinable et que vous souhaitez avoir une compatibilité descendante pour l' API inférieure à 21 , ajoutez les codes suivants à:

Au niveau de l'application build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

Dans la classe Application:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Une manière plus simple qui fonctionne aussi pour moi: button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf

2
Vous avez raison, mais vous êtes Context#.getDrawable(resId)déconseillé, son utilisation peut donc entraîner des problèmes.
aminographie

Fonctionne sans ajouter de classe Application car je n'en ai pas.
Mark Delphi

15

Pour moi, cela a fonctionné:

button.setCompoundDrawablesWithIntrinsicBounds(com.example.project1.R.drawable.ic_launcher, 0, 0, 0);

13
myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

4

J'ai fait ça:

 // Left, top, right, bottom drawables.
            Drawable[] drawables = button.getCompoundDrawables();
            // get left drawable.
            Drawable leftCompoundDrawable = drawables[0];
            // get new drawable.
            Drawable img = getContext().getResources().getDrawable(R.drawable.ic_launcher);
            // set image size (don't change the size values)
            img.setBounds(leftCompoundDrawable.getBounds());
            // set new drawable
            button.setCompoundDrawables(img, null, null, null);

4

Si vous utilisez drawableStart , drawableEnd , drawableTop ou drawableBottom ; vous devez utiliser " setCompoundDrawablesRelativeWithIntrinsicBounds "

edittext.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.anim_search_to_close, 0)

3

A travaillé pour moi. Pour régler le dessin à droite

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)

2

comme le souligne @ Jérémy Reynaud, comme décrit dans cette réponse , le moyen le plus sûr de définir le dessin à gauche sans modifier les valeurs des autres dessinables (en haut, à droite et en bas) consiste à utiliser les valeurs précédentes du bouton avec setCompoundDrawablesWithIntrinsicBounds :

Drawable leftDrawable = getContext().getResources()
                          .getDrawable(R.drawable.yourdrawable);

// Or use ContextCompat
// Drawable leftDrawable = ContextCompat.getDrawable(getContext(),
//                                        R.drawable.yourdrawable);

Drawable[] drawables = button.getCompoundDrawables();
button.setCompoundDrawablesWithIntrinsicBounds(leftDrawable,drawables[1],
                                               drawables[2], drawables[3]);

Ainsi, tous vos tirables précédents seront conservés.


2

Voici la façon de changer la couleur de l'icône de gauche dans le texte d'édition et de la définir dans le côté gauche.

 Drawable img = getResources().getDrawable( R.drawable.user );
img.setBounds( 0, 0, 60, 60 );
mNameEditText.setCompoundDrawables(img,null, null, null);

int color = ContextCompat.getColor(this, R.color.blackColor);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    DrawableCompat.setTint(img, color);

} else {
    img.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}

1

Pourrait être utile:

TextView location;
location=(TextView)view.findViewById(R.id.complain_location);
//in parameter (left,top,right,bottom) any where you wnat to put
location.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.arrow,0);

1

Ajouter une extension Kotlin

Si vous comptez le faire fréquemment, l'ajout d'une extension rend votre code plus lisible. Le bouton étend TextView; utilisez Button si vous voulez être plus étroit.

fun TextView.leftDrawable(@DrawableRes id: Int = 0) {
    this.setCompoundDrawablesWithIntrinsicBounds(id, 0, 0, 0)
}

Pour utiliser l'extension, appelez simplement

view.leftDrawable(R.drawable.my_drawable)

Chaque fois que vous devez effacer, ne passez pas un paramètre ou ne créez pas une autre extension appelée removeDrawables


0

Essaye ça:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
     fillButton[i].setBackground(getBaseContext().getResources().getDrawable(R.drawable.drawable_name));
}
else {
    fillButton[i].setBackgroundColor(Color.argb(255,193,234,203));
}

-8

Essaye ça:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);

myEdtiText.setCompoundDrawablesWithIntrinsicBounds (R.drawable.smiley, 0, 0, 0); travaux
Debasish Ghosh
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.