getColor (int id) ist auf Android 6.0 Marshmallow (API 23) veraltet.

718

Die Resources.getColor(int id)Methode ist veraltet.

@ColorInt
@Deprecated
public int getColor(@ColorRes int id) throws NotFoundException {
    return getColor(id, null);
}

Was sollte ich tun?

Araks
quelle
26
Verwenden Sie ContextCompat.getColor (Kontext, R.color.color_name)
Ashokchakravarthi Nagarajan
Mit dieser oben erwähnten Methode: getColor (Kontext, R.color.your_color); Es ist nicht klar, wie man den "Kontext" erhält. In meinem Fall Android Studio 3.2 funktioniert es nicht, wenn Sie nur den Kontext dort einfügen. Ich finde, das funktioniert bei mir. .setTextColor (Color.RED).
Harry

Antworten:

1347

Ab Android Support Library 23 wurde
eine neue Methode getColor () hinzugefügt ContextCompat.

Seine Beschreibung aus dem offiziellen JavaDoc:

Gibt eine Farbe zurück, die einer bestimmten Ressourcen-ID zugeordnet ist

Ab M wird die zurückgegebene Farbe für das angegebene Kontextthema gestaltet.


Also, rufen Sie einfach an :

ContextCompat.getColor(context, R.color.your_color);


Sie können den ContextCompat.getColor() Quellcode auf GitHub überprüfen .

Araks
quelle
1
Dies sieht nach einer Lösung aus, aber was sollen wir tun, wenn die Fehlermeldung "Sollte hier aufgelöste Farbe anstelle der Ressourcen-ID übergeben wird" angezeigt wird? Soweit ich das beurteilen kann, liegt es wahrscheinlich daran, dass Lint die neue API der Support-Bibliothek nicht erkennt. Vielleicht ist es also der richtige Weg, nur eine Anmerkung @SuppressWarnings ("ResourceAsColor") hinzuzufügen? Ich mag es aber nicht sehr.
Stan
1
Hallo @Stan, können Sie dem Code-Snippet bitte den Methodenaufruf geben, der die "ResourceAsColor" -Lint auslöst?
Araks
"int color = ContextCompat.getColor (this, R.color.orange);" und dann "span = new ForegroundColorSpan (color);". Das Wort, das rot unterstrichen wird, ist "Farbe", wo ich es an "new ForegroundColorSpan ()" übergebe.
Stan
1
@MonicaLabbao oh ... sorry, ich habe deinen Kommentar falsch verstanden! :)
Araks
3
ContextCompatApi23 Dieser Markierungsfehler hat dazu geführt, dass Sie auf ContextCompat
Webserveis
498

tl; dr:

ContextCompat.getColor(context, R.color.my_color)

Erläuterung:

Sie müssen ContextCompat.getColor () verwenden , das Teil der Support V4-Bibliothek ist (es funktioniert für alle vorherigen APIs).

ContextCompat.getColor(context, R.color.my_color)

Wenn Sie die Support-Bibliothek noch nicht verwenden, müssen Sie dem dependenciesArray in Ihrer App die folgende Zeile hinzufügen build.gradle(Hinweis: Dies ist optional, wenn Sie die Appcompat-Bibliothek (V7) bereits verwenden ):

compile 'com.android.support:support-v4:23.0.0' # or any version above

Wenn Sie sich für Themen interessieren, wird in der Dokumentation Folgendes angegeben:

Ab M wird die zurückgegebene Farbe für das angegebene Kontextthema gestaltet

Melvin
quelle
4
Dies sollte die als richtige Antwort ausgewählte sein. Denn in der gegebenen Verbindung von Android Docs, sagen Sie es „ Ab in Mdie zurück Farbe wird für den angegebenen Kontext des Themas gestylt werden.
Bugs Happen
1
kompiliere 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla
@G O'Rilla Wie Sie in der Dokumentation sehen können, ContextCompatstammt die Klasse von SupportV4. AppcompatV7 funktioniert auch, da es auf SupportV4 basiert. Wie sie sagen auf der Support Library Dokumentation , This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.. Es ist also sinnvoll, AppcompatV7die Antwort nicht einzugeben.
Melvin
1
Danke @Melvin, hier ist mein Beispiel, wenn es von Nutzen ist: int colorTwitterBlue = ContextCompat.getColor (this, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGATIVE) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
Lara Ruffle Coles
1
@ Melvin. Was genau bedeutet das, dass die Farbe an das angegebene Kontextthema angepasst wird? Klingt so, als könnte man je nach Thema unterschiedliche Farben für dieselbe Farb-ID definieren. Wie geht das genau?
RobertoCuba
47

Ich möchte die Support-Bibliothek nicht nur für getColor einbinden , also verwende ich so etwas wie

public static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return context.getColor(id);
    } else {
        //noinspection deprecation
        return context.getResources().getColor(id);
    }
}

Ich denke, der Code sollte einwandfrei funktionieren und der veraltete Code getColorkann nicht aus der API <23 verschwinden.

Und das verwende ich in Kotlin:

/**
 * Returns a color associated with a particular resource ID.
 *
 * Wrapper around the deprecated [Resources.getColor][android.content.res.Resources.getColor].
 */
@Suppress("DEPRECATION")
@ColorInt
fun getColorHelper(context: Context, @ColorRes id: Int) =
    if (Build.VERSION.SDK_INT >= 23) context.getColor(id) else context.resources.getColor(id);
Alex Vang
quelle
4
Mit Blick auf den Quellcode macht die Support-Bibliothek genau das so. Ich ziele auf API> = 21 ab, daher möchte ich für diese wenigen Zeilen kein vollständiges Glas einfügen. Beachten Sie, dass Sie die Warnung in Android Studio unterdrücken können, indem Sie über dem veralteten Aufruf "// noinspection deprecation" hinzufügen. Verwenden Sie einen Aktivitätskontext, keinen Anwendungskontext, da sonst möglicherweise Themeninformationen verloren gehen.
personne3000
2
Dies sollte die richtige Antwort sein, obwohl die Support-Bibliothek eine zukunftssicherere Wahl sein kann. Ich stimme jedoch zu, dass Sie diese paar Zeilen besser einbeziehen sollten, wenn dies der einzige Grund ist, für den Sie die Support-Bibliothek einschließen.
Anthonymonori
30

In Android Marshmallow sind viele Methoden veraltet.

Zum Beispiel, um Farbe zu verwenden

ContextCompat.getColor(context, R.color.color_name);

Auch zum Zeichnen verwendbar

ContextCompat.getDrawable(context, R.drawable.drawble_name);
Ashokchakravarthi Nagarajan
quelle
3
Woher kommt der variable Kontext? muss ich es initialisieren? Ich kann es nicht zum Laufen bringen. Mir scheint, Androind hat noch einen langen Weg vor sich. Es macht mich wahnsinnig, wie sehr ich mich bemühe, eine Farbe aus einer XML-Ressource zu bekommen !! Wow
ColdTuna
29

Für alle Kotlin-Benutzer da draußen:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}
Paul Spiesberger
quelle
Eigentlich sollte es sein val color = ContextCompat.getColor(context, R.color.colorPrimary). Die Variable "it" kann alles sein, muss aber ein Kontext sein .
Scott Biggs
itist in diesem Fall das context, da ich benutze um context?.let {zu prüfen ob das contextnicht null ist. Die Funktion getColor()akzeptiert nur einen Nicht-Null-Kontext. Lesen Sie hier mehr darüber letund wie man es benutzt: kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger
4

In Ihrer RecyclerView in Kotlin

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(t: YourObject, listener: OnItemClickListener.YourObjectListener) = with(itemView) {
        textViewcolor.setTextColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary))
        textViewcolor.text = t.name
    }
}
Irvin Joao
quelle
1

Verwenden Sie die getColor(Resources, int, Theme)Methode von ResourcesCompataus der Android Support Library.

int white = new ResourcesCompat().getColor(getResources(), R.color.white, null);

Ich denke, es spiegelt Ihre Frage besser wider als die, getColor(Context, int)nach der ContextCompatSie gefragt haben Resources. Vor API-Level 23 wird das Thema nicht angewendet und die Methode ruft auf, getColor(int)aber Sie erhalten keine veraltete Warnung. Das Thema kann auch sein null.

Pedro
quelle
1
Wenn Sie null als Theme-Argument übergeben, wird die zurückgegebene Farbe NICHT für das aktuelle Theme formatiert. Es könnte also falsch sein.
Araks
1

Wenn Sie die Ressourcen nicht unbedingt benötigen, verwenden Sie parseColor(String):
Color.parseColor("#cc0066")

N. Osil
quelle
1

Wenn Ihre aktuelle min. Die API-Ebene ist 23, Sie können sie einfach so verwenden,getColor() wie wir sie verwenden, um Zeichenfolgenressourcen abzurufen, indem Sie getString():

//example
textView.setTextColor(getColor(R.color.green));
// if `Context` is not available, use with context.getColor()

Sie können Einschränkungen für API-Ebenen unter 23 festlegen:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

aber um es einfach zu halten, können Sie wie folgt als akzeptierte Antwort tun:

textView.setTextColor(ContextCompat.getColor(context, R.color.green))

Aus Ressourcen .

Von ContextCompat AndroidX .

Vom ContextCompat-Support

Blasanka
quelle
0

Ich war auch frustriert. Mein Bedürfnis war sehr einfach. Alles, was ich wollte, war die ARGB-Farbe aus den Ressourcen, also schrieb ich eine einfache statische Methode.

protected static int getARGBColor(Context c, int resId)
        throws Resources.NotFoundException {

    TypedValue color = new TypedValue();
    try {
        c.getResources().getValue(resId, color, true);
    }
    catch (Resources.NotFoundException e) {
        throw(new Resources.NotFoundException(
                  String.format("Failed to find color for resourse id 0x%08x",
                                resId)));
    }
    if (color.type != TYPE_INT_COLOR_ARGB8) {
        throw(new Resources.NotFoundException(
                  String.format(
                      "Resourse id 0x%08x is of type 0x%02d. Expected TYPE_INT_COLOR_ARGB8",
                      resId, color.type))
        );
    }
    return color.data;
}
Steven Smith
quelle