Wie kann ich drawableLeft programmgesteuert auf der Android-Schaltfläche einstellen?


442

Ich erstelle dynamisch Schaltflächen. Ich habe sie zuerst mit XML gestylt und versuche, das folgende XML zu verwenden und es programmatisch zu machen.

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

Das habe ich bisher. Ich kann alles außer dem Zeichnen.

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

Antworten:


1053

Sie können die setCompoundDrawablesMethode verwenden, um dies zu tun. Siehe das Beispiel hier . Ich habe dies ohne das verwendet setBoundsund es hat funktioniert. Sie können es so oder so versuchen.

UPDATE : Kopieren Sie den Code hier, falls der Link ausfällt

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

oder

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

oder

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

@Varun, @Tigger: Ich habe ein Problem damit: Mein Dateimanager zeigt Ordner in einer Listenansicht mit Textansichten und einem Ordnersymbol als drawableLeft. Ich habe Ihre Vorschläge hier versucht, ein "verbotenes Symbol" festzulegen, wenn Sie in einen Ordner ohne Leseberechtigung klicken, und es funktioniert. Wenn Sie jedoch den Ordner wechseln und der Adapter neu geladen wird, bleibt das verbotene Symbol bestehen (dh es wird drawableLeftnicht neu gezeichnet). Wissen Sie, wie Sie sich notifyDataSetChangedauch für die bewerben können drawableLeft, ohne eine Schleife zu machen? Vielen Dank!
Luis A. Florit

@ LuisA.Florit Es hört sich so an, als hätten Sie eine Frage zum Neuzeichnen eines ListviewElements, wenn sich die Daten ändern - was sich nicht wirklich auf diese Frage oder Antwort bezieht. Ich schlage vor, Sie posten eine Frage anstelle eines Kommentars.
Tigger

@Tigger: Nun, ich habe das Symbol auch mit deinem Trick und einer Schleife über die verbotenen Verzeichnisse zurückgesetzt. Vielleicht ist dies besser, als alle ListView-Elemente neu zu zeichnen ... Trotzdem danke!
Luis A. Florit

3
Ich sehe etwas Seltsames in meiner App. Das setCompoundDrawablesWithIntrinsicBounds( 0, 0, R.drawable.money, 0 )funktioniert nicht, wenn ich das drawableRight in der layout.xml definiere. Wenn ich das ursprüngliche Symbol im Inneren einstelle onCreate(), funktioniert die Änderung. Könnte es mit API 19 zusammenhängen?
Injektor

Beispiellink wird nicht geöffnet. Gibt es einen alternativen Link?
Yogesh Umesh Vaity

100

Einfach können Sie dies auch versuchen

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

4
R.drawable.smiley sollte anstelle der ersten 0 (des ersten Parameters) und nicht der letzten sein, da die Definition dieser Methode lautet: {public void setCompoundDrawablesWithIntrinsicBounds (int left, int top, int right, int bottom)}
arniotaki

Wie kann ich auch Polster hinzufügen? Auf diese Weise gibt es nicht viel Abstand zwischen dem Zeichenbaren und dem Text.
AdamMc331

16

• • Kotlin Version

Verwenden Sie das folgende Snippet, um der Schaltfläche ein Zeichenelement hinzuzufügen:

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

.

• • Important Point in Using Android Vector Drawable

Wenn Sie einen Android-Vektor zum Zeichnen verwenden und eine Abwärtskompatibilität für API unter 21 wünschen , fügen Sie die folgenden Codes hinzu:

In App-Ebene build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

In der Anwendungsklasse:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Ein einfacher Weg, der auch für mich funktioniert: button.setCompoundDrawablesWithIntrinsicBounds (getDrawable (R.drawable.ic_favorite_white_16dp), null, null, null)
juangalf

2
Sie haben Recht, sind aber Context#.getDrawable(resId)veraltet, sodass die Verwendung einige Probleme verursachen kann.
Aminographie

Funktioniert ohne Hinzufügen einer Anwendungsklasse, da ich keine habe.
Mark Delphi

15

Bei mir hat es geklappt:

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

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

4

Ich war das:

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

Wenn Sie drawableStart , drawableEnd , drawableTop oder drawableBottom verwenden ; Sie müssen " setCompoundDrawablesRelativeWithIntrinsicBounds " verwenden.

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

3

Hat für mich gearbeitet. Zum Zeichnen rechts einstellbar

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

2

Wie @ Jérémy Reynaud darauf hinweist, wie in dieser Antwort beschrieben , besteht die sicherste Möglichkeit, das linke Zeichenelement festzulegen, ohne die Werte der anderen Zeichenelemente (oben, rechts und unten) zu ändern, darin, die vorherigen Werte über die Schaltfläche mit setCompoundDrawablesWithIntrinsicBounds zu verwenden :

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

So bleiben alle Ihre vorherigen Zeichen erhalten.


2

Im Folgenden wird beschrieben, wie Sie die Farbe des linken Symbols im Bearbeitungstext ändern und auf der linken Seite festlegen können.

 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

Könnte hilfreich sein:

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

Fügen Sie eine Kotlin-Erweiterung hinzu

Wenn Sie dies häufig tun, wird Ihr Code durch Hinzufügen einer Erweiterung besser lesbar. Die Schaltfläche erweitert TextView. Verwenden Sie die Schaltfläche, wenn Sie enger sein möchten.

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

Um die Nebenstelle zu nutzen, rufen Sie einfach an

view.leftDrawable(R.drawable.my_drawable)

Übergeben Sie bei jedem Löschen keinen Parameter und lassen Sie keine andere Erweiterung namens aufrufen removeDrawables


0

Versuche dies:

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

Versuche dies:

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

myEdtiText.setCompoundDrawablesWithIntrinsicBounds (R.drawable.smiley, 0, 0, 0); funktioniert
Debasish Ghosh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.