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.

Stephane
quelle
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));
Kaltes Feuer
quelle
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").

dimsuz
quelle
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));
tse
quelle
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.

Shayne3000
quelle
@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.

Chris K.
quelle
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
6

So geht's in Kotlin:

view.background.setTint(ContextCompat.getColor(context, textColor))
Amin Keshavarzian
quelle
danke, es hat gut funktioniert!
Stoica Mircea
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;
}
mac229
quelle
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))
Amin Keshavarzian
quelle
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.

Matt Jenje
quelle
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.

Zeigen Sie Ihre Arbeit
quelle
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
Saurabh Singh
quelle
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)
Azizjon Kholmatov
quelle
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
Coldembrace
quelle
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 .

Matt Wolfe
quelle