Come impostare programmabilmente drawableLeft sul pulsante Android?


442

Sto creando dinamicamente pulsanti. Li ho disegnati prima usando XML, e sto provando a prendere l'XML qui sotto e renderlo programmatico.

<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>

Questo è quello che ho finora. Posso fare tutto tranne il disegnabile.

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);

Risposte:


1055

È possibile utilizzare il setCompoundDrawablesmetodo per farlo. Vedi l'esempio qui . L'ho usato senza usare setBoundse ha funzionato. Puoi provare in entrambi i modi.

AGGIORNAMENTO : Copiando qui il codice in caso di collegamento inattivo

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

o

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

o

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

@Varun, @Tigger: Ho un problema con questo: Il mio file manager mostra le cartelle in una lista con visualizzazioni di testo e un'icona di cartella come drawableLeft. Ho provato i tuoi suggerimenti qui per impostare un'icona vietata quando fai clic in una cartella senza autorizzazioni di lettura e funziona. Tuttavia, quando si cambiano le cartelle e l'adattatore viene ricaricato, l'icona proibita persiste (ovvero drawableLeftnon viene ridisegnata). Sai fare domanda notifyDataSetChangedanche per drawableLeft, senza fare un ciclo? Grazie!
— Luis A. Florit,

@ LuisA.Florit Sembra che tu abbia una domanda relativa al ridisegno di un Listviewelemento quando i dati cambiano, il che non si riferisce realmente a questa domanda o risposta. Ti suggerisco di pubblicare una domanda anziché un commento.
— Tigro,

@Tigger: Bene, ho ripristinato l'icona usando anche il tuo trucco, e un ciclo sopra le directory proibite. Forse è meglio che ridisegnare tutti gli elementi di ListView ... Grazie comunque!
— Luis A. Florit,

3
Vedo qualcosa di strano nella mia app. Il setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )non funziona, se io definisco il drawableRight nel layout.xml. Se imposto l'icona originale all'interno onCreate(), la modifica funziona. Potrebbe essere correlato all'API 19?
— injecteer,

Il link di esempio non si apre. C'è qualche link alternativo?
— Yogesh Umesh Vaity,

100

Puoi semplicemente provare anche questo

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

4
R.drawable.smiley dovrebbe essere al posto del primo 0 (il primo parametro) non l'ultimo perché la definizione di questo metodo è: {public void setCompoundDrawablesWithIntrinsicBounds (int left, int top, int right, int bottom)}
— arniotaki

Come posso aggiungere anche l'imbottitura? Non c'è molta imbottitura tra il disegno e il testo in questo modo.
— AdamMc331,

16

• Kotlin Version

Usa lo snippet di seguito per aggiungere un disegno a sinistra al pulsante:

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

.

• Important Point in Using Android Vector Drawable

Quando si utilizza un disegno vettoriale Android e si desidera avere una compatibilità con le versioni precedenti per API inferiore a 21 , aggiungere i seguenti codici a:

A livello di app build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

Nella classe di applicazione:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Un modo più semplice che funziona anche per me: button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
— juangalf

2
Hai ragione, ma Context#.getDrawable(resId)è deprecato, quindi l'utilizzo potrebbe causare alcuni problemi.
— aminografia,

Funziona senza aggiungere in classe Application poiché non ne ho uno.
— Mark Delphi,

15

Per me ha funzionato:

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

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

4

L'ho fatto:

 // 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

Se si utilizza drawableStart , drawableEnd , drawableTop o drawableBottom ; devi usare " setCompoundDrawablesRelativeWithIntrinsicBounds "

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

3

Ha funzionato per me. Per impostare il disegno a destra

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

2

come @ Jérémy Reynaud sottolineando, come descritto in questa risposta , il modo più sicuro per impostare il drawable sinistro senza cambiare i valori degli altri drawable (in alto, a destra e in basso) è usando i valori precedenti dal pulsante con 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]);

Quindi tutti i tuoi disegni precedenti verranno conservati.


2

Di seguito è riportato il modo per cambiare il colore dell'icona sinistra nel testo di modifica e impostarlo sul lato sinistro.

 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

Potrebbe essere 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

Aggiungi un'estensione Kotlin

Se lo farai frequentemente, l'aggiunta di un'estensione rende il tuo codice più leggibile. Il pulsante estende TextView; usa il pulsante se vuoi essere più stretto.

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

Per utilizzare l'estensione, è sufficiente chiamare

view.leftDrawable(R.drawable.my_drawable)

Ogni volta che è necessario cancellare, non passare un parametro o fare un altro interno chiamato removeDrawables


0

Prova questo:

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

Prova questo:

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

myEdtiText.setCompoundDrawablesWithIntrinsicBounds (R.drawable.smiley, 0, 0, 0); funziona
— Debasish Ghosh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.