So fügen Sie programmgesteuert Schaltflächen hinzu


118

In der neuen AppCompat-Bibliothek können wir die Schaltfläche folgendermaßen tönen:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/follow"
    android:id="@+id/button_follow"
    android:backgroundTint="@color/blue_100"
    />

Wie kann ich den Farbton der Schaltfläche programmgesteuert in meinem Code einstellen? Ich versuche im Grunde, eine bedingte Färbung der Schaltfläche basierend auf einigen Benutzereingaben zu implementieren.


Sind Sie sicher, dass Android: backgroundTint an Pre-Lollipop arbeitet? Ich teste sowohl mit Button als auch mit ApCompatButton, aber backgroundTint scheint nur mit Lollipop zu funktionieren.
Sharj

1
Bitte überprüfen Sie diese Antwort .
Amit Vaghela

Antworten:


159

Gemäß der Dokumentation der verwandte Methode android:backgroundTintist setBackgroundTintList (ColorStateList Liste)

Aktualisieren

Folgen Sie diesem Link , um zu erfahren, wie Sie eine Farbstatuslistenressource erstellen.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="#your_color_here" />
</selector>

dann laden Sie es mit

setBackgroundTintList(contextInstance.getResources().getColorStateList(R.color.your_xml_name));

wo contextInstanceist eine Instanz von aContext


mit AppCompart

btnTag.setSupportButtonTintList(ContextCompat.getColorStateList(Activity.this, R.color.colorPrimary));

Das ist keine Farbe, sondern eine ColorStateList. Wie kann man das nutzen?
Stephane

4
Ich verstehe jetzt, wie es geht, danke, aber warum sollte Android Ihnen nicht erlauben, eine Farbe nur manuell zu verwenden? Muss ich für jede Farbe jeder Schaltfläche, die ich habe, eine XML für eine ColorStateList erstellen? Das scheint mir eine Verschwendung zu sein
Stephane

2
setBackgroundTintList benötigt API 21, auch wenn Sie es auf AppCompatButton aufrufen.
Sharj

29
Die AppCompat-Unterstützungsbibliothek bietet einen statischen Helfer: Dieser ViewCompat.setBackgroundTintList(View, ColorStateList)kann bis zur API 4 verwendet werden. Er funktioniert jedoch nur für Ansichten, die TintableBackgroundViewbeispielsweise implementiert werden AppCompatButton(anstelle der üblichen Button).
Jon Adams

1
Die Verwendung ViewCompat.setBackgroundTintList(View, ColorStateList)von @Jon Adams ist jetzt noch sinnvoller, da View.setSupportButtonTintList nur mit RestrictToAnmerkungen versehen ist. Details hier: developer.android.com/reference/android/support/annotation/…
AlexKost

75

Du könntest benutzen

button.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(R.id.blue_100)));

Ich würde Ihnen jedoch empfehlen, eine Zeichnungsfarbe für die Unterstützungsbibliothek zu verwenden, die erst gestern veröffentlicht wurde:

Drawable drawable = ...;

// Wrap the drawable so that future tinting calls work
// on pre-v21 devices. Always use the returned drawable.
drawable = DrawableCompat.wrap(drawable);

// We can now set a tint
DrawableCompat.setTint(drawable, Color.RED);
// ...or a tint list
DrawableCompat.setTintList(drawable, myColorStateList);
// ...and a different tint mode
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_OVER);

Weitere Informationen finden Sie in diesem Blogbeitrag (siehe Abschnitt "Zeichenbare Tönung").


2
Könnten Sie vollständigen Code bereitstellen, um den Farbton mit Ihrer Methode einzustellen?
M. Usman Khan

Beste Antwort...!
Gokul Nath KP

60

Scheint, als hätten Ansichten eigene Mechaniken für das Farbtonmanagement, daher wird eine bessere Farbtonliste erstellt:

ViewCompat.setBackgroundTintList(
    editText, 
    ColorStateList.valueOf(errorColor));

Es ist viel besser, es auf diese Weise zu verwenden, damit Sie Abwärtskompatibilität von API 4 erhalten!
xarlymg89

eine der besten Lösungen.
Atif AbbAsi

20

Informationen zur ordnungsgemäßen Erweiterung der Antwort von dimsuz durch Bereitstellung einer realen Codesituation finden Sie im folgenden Codeausschnitt:

    Drawable buttonDrawable = button.getBackground();
    buttonDrawable = DrawableCompat.wrap(buttonDrawable);
    //the color is a direct color int and not a color resource
    DrawableCompat.setTint(buttonDrawable, Color.RED);
    button.setBackground(buttonDrawable);

Diese Lösung ist für das Szenario vorgesehen, in dem ein Zeichen als Hintergrund für die Schaltfläche verwendet wird. Es funktioniert auch auf Pre-Lollipop-Geräten.


@TruptiNasit Freut mich das zu hören.
Shayne3000

Hat für mich gearbeitet. Danke dir.
Wesley Franks

1
@wesleyfranks Gern geschehen. Ich bin froh zu hören, dass es funktioniert hat.
Shayne3000

7

Haben Sie so etwas versucht?

button.setBackgroundTintList(getResources().getColorStateList(R.id.blue_100));

Beachten Sie, dass getResources () nur in einer Aktivität funktioniert. Es kann aber auch in jedem Kontext aufgerufen werden.


Sie können eine XML wie hier beschrieben erstellen: developer.android.com/reference/android/content/res/…
Chris K.

getColorStateList scheint veraltet zu sein.
Cloudsurfin

1
setBackgroundTintList scheint API Level 21
Nashe

1
Taste. setBackgroundTintList (ContextCompat.getColorStateList (context, R.color.blue)); arbeitete für mich
jesto paul


5

Sie können DrawableCompat verwenden, z

public static Drawable setTint(Drawable drawable, int color) {
    final Drawable newDrawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTint(newDrawable, color);
    return newDrawable;
}

5

Dies ist in der neuen Materialschaltfläche aus der Materialdesignbibliothek einfach zu handhaben. Fügen Sie zunächst die Abhängigkeit hinzu:

implementation 'com.google.android.material:material:1.1.0-alpha07'

Verwenden Sie dann in Ihrem XML Folgendes für Ihre Schaltfläche:

<com.google.android.material.button.MaterialButton
    android:id="@+id/accept"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/i_accept"
    android:textSize="18sp"
    app:backgroundTint="@color/grayBackground_500" />

und wenn Sie die Farbe ändern möchten, ist hier der Code in Kotlin: Er ist nicht veraltet und kann vor Android 21 verwendet werden:

accept.backgroundTintList = ColorStateList.valueOf(ResourcesCompat.getColor(resources, 
R.color.colorPrimary, theme))

Gibt es eine ähnliche für die Textfarbe selbst?
Android-Entwickler

Sie meinen Text als Schaltfläche und möchten die Farbe des Hintergrunds ändern?
Amin Keshavarzian

4

Ich habe es geschafft, meine zur Arbeit zu bringen, indem ich sie benutzt habe CompoundButtonCompat.setButtonTintList(button, colour).

Nach meinem Verständnis funktioniert dies unabhängig von der Android-Version.


3

Ich hatte ein ähnliches Problem. Ich wollte einen komplexen zeichnbaren Hintergrund für eine Ansicht einfärben, die auf einem Farbwert (int) basiert. Es ist mir gelungen, den Code zu verwenden:

ColorStateList csl = new ColorStateList(new int[][]{{}}, new int[]{color});
textView.setBackgroundTintList(csl);

Wobei Farbe ein int-Wert ist, der die erforderliche Farbe darstellt. Dies stellt die einfache XML ColorStateList dar:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:color="color here"/>
</selector>

Hoffe das hilft.


2
Minimal erforderliche API-Stufe 21
Forsberg

ColorStateList.valueOf(ColorInt)
Nun,

2

Für ImageButton können Sie Folgendes verwenden:

favoriteImageButton.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

setColorFilter ist nicht für Buttons definiert
Jérémy

Es ist für ImageButton.
Saurabh Singh

Oh ok, ich wusste nichts davon. Aber OP fragt nach Button. Können Sie Ihre Antwort mit diesem Detail bearbeiten, damit ich meine Ablehnung entfernen kann?
Jérémy

2

Wenn Sie Kotlinund verwenden Material Design, können Sie die Farbe MaterialButtonwie folgt ändern :

myButton.background.setTintList(ContextCompat.getColorStateList(context, R.color.myColor))

Sie können es noch besser verbessern, indem Sie eine Erweiterungsfunktion für Sie erstellen, um Ihren MaterialButtonCode lesbarer und Ihre Codierung etwas komfortabler zu machen:

fun MaterialButton.changeColor(color: Int) {
    this.background.setTintList(ContextCompat.getColorStateList(context, color))
}

Dann können Sie Ihre Funktion überall so verwenden:

myButton.changeColor(R.color.myColor)

1

Zusätzlich zur Antwort von Shayne3000 können Sie auch eine Farbressource verwenden (nicht nur eine int-Farbe). Kotlin- Version:

var indicatorViewDrawable = itemHolder.indicatorView.background
indicatorViewDrawable = DrawableCompat.wrap(indicatorViewDrawable)
val color = ResourcesCompat.getColor(context.resources, R.color.AppGreenColor, null) // get your color from resources
DrawableCompat.setTint(indicatorViewDrawable, color)
itemHolder.indicatorView.background = indicatorViewDrawable

0

Die hier vorgeschlagene Antwort funktioniert unter Android 5.0 nicht richtig, wenn Ihre XML-basierte Farbstatusliste auf Themenattribute verweist. Zum Beispiel habe ich eine XML-Farbstatusliste wie folgt:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="?colorPrimary" android:state_enabled="true"/>
    <item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>

Dies als Hintergrund zu verwendenTint von XML funktioniert gut auf Android 5.0 und allem anderen. Wenn ich jedoch versuche, dies in Code wie folgt einzustellen:

(Tu das nicht)

myButton.setSupportButtonTintList(ContextCompat.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

Es spielt eigentlich keine Rolle, ob ich die Aktivität oder den Kontext der Schaltfläche an die ContextCompat.getColorStateList () -Methode übergebe. Außerdem wird mir weder die richtige Farbstatusliste für das Thema angezeigt, in dem sich die Schaltfläche befindet. Dies liegt daran, dass die Verwendung von Designattributen in Farbstatuslisten erst in API 23 unterstützt wurde und ContextCompat nichts Besonderes unternimmt, um diese Probleme zu beheben. Stattdessen müssen Sie AppCompatResources.getColorStateList () verwenden, das auf Geräten <API 23 eine eigene Ressourcenanalyse / Themenattributauflösung durchführt .

Stattdessen müssen Sie Folgendes verwenden:

myButton.setSupportBackgroundTintList(AppCompatResources.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

TLDR: Verwenden Sie AppCompatResources und nicht -ContextCompat-, wenn Sie aufgelöste Themenressourcen für alle API-Versionen von Android benötigen.

Weitere Informationen zum Thema finden Sie in diesem Artikel .

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.