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

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
quelle
@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);
Jignesh Ansodariya
quelle
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)
    }

}
Aminographie
quelle
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);
Swapnil Saha
quelle
13
myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);
Gnganpath
quelle
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);
user1564762
quelle
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)
Mete
quelle
3

Hat für mich gearbeitet. Zum Zeichnen rechts einstellbar

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)
Shaon
quelle
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.

ישו אוהב אותך
quelle
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);
}
Rajneesh Shukla
quelle
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);
Muhaiminur Rahman
quelle
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

Gibolt
quelle
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));
}
Maifee Ul Asad
quelle
-8

Versuche dies:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);
user2969017
quelle
myEdtiText.setCompoundDrawablesWithIntrinsicBounds (R.drawable.smiley, 0, 0, 0); funktioniert
Debasish Ghosh