Holen Sie sich color-int aus der Farbressource

447

Gibt es eine Möglichkeit, ein Color-Int aus einer Farbressource abzurufen? Ich versuche, die einzelnen roten, blauen und grünen Komponenten einer in der Ressource definierten Farbe (R.color.myColor) abzurufen, damit ich die Werte von drei Suchleisten auf eine bestimmte Ebene festlegen kann.

ataulm
quelle

Antworten:

927

Sie können verwenden:

getResources().getColor(R.color.idname);

Überprüfen Sie hier, wie Sie benutzerdefinierte Farben definieren:

http://sree.cc/google/android/defining-custom-colors-using-xml-in-android

EDIT (1): Da getColor(int id)ist veraltet jetzt, diese zu verwenden:

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

(hinzugefügt in Support-Bibliothek 23)

EDIT (2):

Der folgende Code kann sowohl für Pre- als auch für Post-Marshmallow verwendet werden (API 23).

ResourcesCompat.getColor(getResources(), R.color.your_color, null); //without theme

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme
saß
quelle
7
was ist mit android.R.color.some_color :-(
Blundell
17
@Blundell uhh, keine Ahnung, ob Sie es jetzt brauchen, aber das funktioniert auch für android.R.color.some_colorzB: getResources().getColor(android.R.color.holo_blue_bright)(zumindest auf API 17)
ataulm
30
getColor () ist jetzt veraltet. Sie können Folgendes verwenden: ContextCompat.getColor (context, R.color.your_color);
Ricardo
2
Mir ist klar, dass Sie nicht derjenige sind, der die Änderungen vorgenommen hat, aber was ist der Unterschied zwischen ContextCompatund ResourcesCompat? Wenn es keinen praktischen Unterschied gibt, wäre es weniger verwirrend, wenn Sie einen davon aus Ihrer Antwort entfernen würden.
Suragch
14
Warum hat Google das Bedürfnis, eine vollkommen gute Funktion für diese schreckliche App-Kompaktbibliothek zu verwerfen? Es ist scheiße, beides zu haben.
Andrew S
116

Basierend auf der neuen Android Support Library (und diesem Update) sollten Sie jetzt anrufen:

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

Laut Dokumentation :

public int getColor (int id)

Diese Methode wurde in API-Level 23 nicht mehr unterstützt . Verwenden Sie stattdessen getColor (int, Theme)

Es ist die gleiche Lösung für getResources().getColorStateList(id):

Sie müssen es so ändern:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

In Bezug auf die ThemeOverlayVerwendung des Kontextes der nächsten Ansicht:

val color = ContextCompat.getColor(
  closestView.context,
  R.color.name.color
)

Auf diese Weise erhalten Sie die richtige Farbe basierend auf Ihrem ThemeOverlay.

Wird besonders benötigt, wenn Sie in derselben Aktivität verschiedene Themen verwenden, z. B. ein dunkles / helles Thema. Wenn Sie mehr über Themen und Stile erfahren möchten, wird dieser Vortrag empfohlen: Entwickeln von Themen mit Stil

Nick Butcher - Droidcon Berlin - Themen mit Stil entwickeln

Ultimo_m
quelle
10
Für diejenigen, die sich fragen, was als Thema in der neuen Methode ThemegetColor(R.color.my_color, null)
ausgefüllt
hmm ... das sagen alle, aber ich kann es nicht zum Laufen bringen. Muss ich den Kontext initialisieren? Derzeit erhalte ich "Symbol 'Kontext' kann nicht aufgelöst werden"
ColdTuna
Um sicherzustellen, dass Sie es richtig machen, versuchen Sie es innerhalb von onCreate der Aktivität aufzurufen. Um dann den Kontext zu erhalten, müssen Sie getContext () oder einfach "this"
aufrufen
35

Definieren Sie Ihre Farbe

values ​​/ color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- color int as #AARRGGBB (alpha, red, green, blue) -->
    <color name="orange">#fff3632b</color>
    ...
    <color name="my_view_color">@color/orange</color>

</resources>

Holen Sie sich die Farbe int und stellen Sie sie ein

int backgroundColor = ContextCompat.getColor(context, R.color.my_view_color);
// Color backgroundColor = ... (Don't do this. The color is just an int.)

myView.setBackgroundColor(backgroundColor);

Siehe auch

Suragch
quelle
1
kannst du nur getResources()in einem Activityoder verwenden Fragment?
Zapnologica
2
@Zapnologica, siehe Antworten auf diese Frage für Gedanken zur Verwendung getResources()außerhalb einer Aktivität oder eines Fragments.
Suragch
1
@Zapnologica Nr. getResources()ist auch als öffentliche API für alle Implementierungen von Context und auch für Views verfügbar.
Ataulm
7

Bester Ansatz

Als Antwort von @sat ist ein guter Ansatz, um Farbe zu erhalten

ResourcesCompat.getColor(getResources(), R.color.your_color, null);

oder verwenden Sie die folgende getResources()Methode , wenn Sie keinen Zugriff auf die Methode haben.

Context context  = getContext(); // like Dialog class
ResourcesCompat.getColor(context.getResources(), R.color.your_color, null);

Was ich tue ist

public void someMethod(){
    ...
    ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);
}

Es ist am einfachsten überall in Ihrer App zu verwenden! Selbst in der Util-Klasse oder einer Klasse, in der Sie weder Context noch getResource () haben

Problem (wenn Sie keinen Kontext haben)

Wenn Sie keinen ContextZugriff haben , wie eine Methode in Ihrer UtilKlasse.

Nehmen Sie die folgende Methode ohne Kontext an.

public void someMethod(){
    ...
    // can't use getResource() without Context.
}

Jetzt werden Sie Contextals Parameter in dieser Methode übergeben und verwendengetResources().

public void someMethod(Context context){
    ...
    context.getResources...
}

Hier ist eine einzigartige Bonuslösung, mit der Sie von überall auf Ressourcen zugreifen können Util class. Fügen Sie ResourcesIhrer ApplicationKlasse hinzu oder erstellen Sie eine, wenn sie nicht vorhanden ist.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static App mInstance;
    private static Resources res;


    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        res = getResources();
    }

    public static App getInstance() {
        return mInstance;
    }

    public static Resources getResourses() {
        return res;
    }

}

Fügen Sie Ihrem manifest.xml <applicationTag ein Namensfeld hinzu. (Wenn nicht bereits hinzugefügt)

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Jetzt können Sie loslegen. Verwenden Sie ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);überall in der App.

Khemraj
quelle
5

Ich habe aktualisiert, um ContextCompat.getColor(context, R.color.your_color);aber manchmal (auf einigen Geräten / Android-Versionen. Ich bin nicht sicher), dass ein NullPointerExcepiton verursacht.

Damit es auf allen Geräten / Versionen funktioniert, greife ich bei einem Nullzeiger auf die alte Vorgehensweise zurück.

try {
    textView.setTextColor(ContextCompat.getColor(getActivity(), R.color.text_grey_dark));
}
catch(NullPointerException e) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        textView.setTextColor(getContext().getColor(R.color.text_grey_dark));
    }
    else {
        textView.setTextColor(getResources().getColor(R.color.text_grey_dark));
    }
}
Ninjachippie
quelle
Warum nicht in allen Fällen die alte Version verwenden oder, wenn Sie die Version trotzdem überprüfen, die neue API verwenden, Resources.getColor(int, Theme)wenn Sie können? Sie sollten keine Laufzeitausnahmen abfangen.
Ataulm
Nur OCD, nehme ich an. ContextCompat scheint mir der zukunftssichere und damit der richtige Weg zu sein. Mein Ansatz ist also, es richtig zu machen. Und wenn dies fehlschlägt (auf alten Geräten oder was auch immer), machen Sie es auf die alte Weise. Warum sollte ich zur Laufzeit keine Ausnahmen abfangen?
Ninjachippie
1

Für weitere Informationen zu einem anderen Anwendungsfall, der dazu beitragen kann, diese Frage in den Suchergebnissen zu beantworten, wollte ich Alpha auf eine in meinen Ressourcen definierte Farbe anwenden.

Verwenden Sie die richtige Antwort von @ sat:

int alpha = ... // 0-255, calculated based on some business logic
int actionBarBackground = getResources().getColor(R.color.actionBarBackground);
int actionBarBackgroundWithAlpha = Color.argb(
        alpha,
        Color.red(actionbarBackground),
        Color.green(actionbarBackground),
        Color.blue(actionbarBackground)
);
ataulm
quelle
1

Einen einfacheren Weg gefunden, der auch funktioniert:

Color.parseColor(getString(R.color.idname);
Geckoflume
quelle
Interessant, wusste nicht, dass man die Farbe auf diese Weise als Zeichenfolge erhalten kann. Ich denke nicht, dass es einfacher ist, aber es ist interessant 😅
ataulm
0

Der Zugriff auf Farben aus einer Nicht-Aktivitätsklasse kann schwierig sein. Eine der Alternativen, die ich gefunden habe, war die Verwendung enum. enumbietet viel Flexibilität.

public enum Colors
{
  COLOR0(0x26, 0x32, 0x38),    // R, G, B
  COLOR1(0xD8, 0x1B, 0x60),
  COLOR2(0xFF, 0xFF, 0x72),
  COLOR3(0x64, 0xDD, 0x17);


  private final int R;
  private final int G;
  private final int B;

  Colors(final int R, final int G, final int B)
  {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public int getColor()
  {
    return (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff);
  }

  public int getR()
  {
    return R;
  }

  public int getG()
  {
    return G;
  }

  public int getB()
  {
    return B;
  }
}
Verwechseln
quelle
0

Neueste Arbeitsmethode:

getColor(R.color.snackBarAction)
zohaib Ansari
quelle
0

Wenn Ihre aktuelle min. Die API-Stufe ist 23, Sie können sie einfach so verwenden, getColor()wie wir sie verwenden für getString():

//example
textView.setTextColor(getColor(R.color.green));
// if context is not available(ex: not in activity) use with context.getColor()

Wenn Sie unter der API-Ebene möchten 23, verwenden Sie einfach Folgendes :

textView.setTextColor(getResources().getColor(R.color.green));

Beachten Sie jedoch, dass dies getResources().getColor()auf API-Ebene veraltet ist 23. In diesem Fall ersetzen Sie oben durch:

textView.setTextColor(ContextCompat.getColor(this /*context*/, R.color.green)) //Im in an activity, so I can use `this`

ContextCompat : Hilfsprogramm für den Zugriff auf Funktionen inContext

Wenn Sie möchten, können Sie folgende Einschränkungen SDK_INTvornehmen:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}
Blasanka
quelle
0
ContextCompat.getColor(context, R.color.your_color);

in der Aktivität

ContextCompat.getColor(actvityname.this, R.color.your_color);

in Fragment

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

zum Beispiel:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
indrajeet jyoti
quelle