Wie bekomme ich programmgesteuert Akzentfarben?

85

Wie würde man die Akzentfarbe, die in Stilen wie unten festgelegt ist, programmgesteuert abrufen?

    <item name="android:colorAccent">@color/material_green_500</item>
Jakob
quelle
3
Jeder, der abstimmt, sollte sich in der Tat sehr frei fühlen, seine Gedanken in einem Kommentar zu veröffentlichen ...
Jakob

Antworten:

128

Sie können es folgendermaßen aus dem aktuellen Thema abrufen:

private int fetchAccentColor() {
    TypedValue typedValue = new TypedValue();

    TypedArray a = mContext.obtainStyledAttributes(typedValue.data, new int[] { R.attr.colorAccent });
    int color = a.getColor(0, 0);

    a.recycle();

    return color;
}
rciovati
quelle
Was ist mit der Support-Version?
DariusL
4
Dies ist die Support-Version.
Rciovati
Können wir die RGB-Zeichenfolge in colorPrimary in styles.xml oder color.xml festlegen?
Tanveer Bulsari
2
Dies gibt eine negative Zahl für mich zurück. Ist dies immer noch der gültige Weg, um die Akzentfarbe zu erhalten?
Naveed
1
Auf was typedValue.data verweist?
GPack
43

Das hat auch bei mir funktioniert:

public static int getThemeAccentColor (final Context context) {
    final TypedValue value = new TypedValue ();
    context.getTheme ().resolveAttribute (R.attr.colorAccent, value, true);
    return value.data;
}
copolii
quelle
Ich bekomme das gleiche Problem auch in dieser Lösung, negativer Wert, und es fällt :(
Batsheva
2
Negativer Wert ist in Ordnung. Es ist eine Farbe!
Copolii
aber meine Anwendung bricht zusammen, ohne dass eine Ressource gefunden wurde ... das passiert nicht, wenn ich eine normale Farbe auftrage! Der Wert ist also nicht in Ordnung
Batsheva
Woher kommt dann der negative Wert, wenn die Ressource nicht gefunden wird? Ich sage nur, dass 0xff2506ac (zum Beispiel) eine negative Zahl und ein gültiger Farbwert ist.
Copolii
2
Der negative Wert, den Sie erhalten, ist die tatsächliche Farbe, nicht die Ressourcen-ID. Verwenden Sie es nicht als Ressourcen-ID.
Copolii
28
private static int getThemeAccentColor(Context context) {
    int colorAttr;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        colorAttr = android.R.attr.colorAccent;
    } else {
        //Get colorAccent defined for AppCompat
        colorAttr = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
    }
    TypedValue outValue = new TypedValue();
    context.getTheme().resolveAttribute(colorAttr, outValue, true);
    return outValue.data;
}
XYz Amos
quelle
2
Dies ist die einzige Antwort, die nicht auf dem Import der App R-Klasse beruht, die sich ideal zum Erstellen benutzerdefinierter Ansichten eignet.
Allan Veloso
11

Ich habe eine statische Methode für eine Utils-Klasse, um die Farben aus dem aktuellen Thema zu erhalten. Meistens ist colorPrimary, colorPrimaryDark und akzentfarbe, aber Sie können noch viel mehr bekommen.

@ColorInt
public static int getThemeColor
(
        @NonNull final Context context,
        @AttrRes final int attributeColor
)
{
    final TypedValue value = new TypedValue();
    context.getTheme ().resolveAttribute (attributeColor, value, true);
    return value.data;
}
Sotti
quelle
11

Für diejenigen unter Ihnen, die Kotlin verwenden

fun Context.themeColor(@AttrRes attrRes: Int): Int {
    val typedValue = TypedValue()
    theme.resolveAttribute (attrRes, typedValue, true)
    return typedValue.data
}
Kevin
quelle
7

Hier ist meine Meinung dazu:

public static String getThemeColorInHex(@NonNull Context context, @NonNull String colorName, @AttrRes int attribute) {
    TypedValue outValue = new TypedValue();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        context.getTheme().resolveAttribute(attribute, outValue, true);
    } else {
        // get color defined for AppCompat
        int appCompatAttribute = context.getResources().getIdentifier(colorName, "attr", context.getPackageName());
        context.getTheme().resolveAttribute(appCompatAttribute, outValue, true);
    }
    return String.format("#%06X", (0xFFFFFF & outValue.data));
}

Verwendung:

    String windowBackgroundHex = getThemeColorInHex(this, "windowBackground", android.R.attr.windowBackground);
    String primaryColorHex = getThemeColorInHex(this, "colorPrimary", R.attr.colorPrimary);
Esdras Lopez
quelle
2
Das String.format()hilft zu erklären, wie der negative ganzzahlige Wert in eine hexadezimale Farbzeichenfolge konvertiert wird.
Mr-IDE
1
Dies ist eine viel bessere / allgemeinere Lösung als die akzeptierte Antwort auf diese Frage!
Nilesh Pawar
Ebenfalls nützlich: stackoverflow.com/questions/6539879/…
Mr-IDE
1

Kotlin-Lösung:

    context.obtainStyledAttributes(TypedValue().data, intArrayOf(R.attr.colorAccent)).let {
        Log.d("AppLog", "color:${it.getColor(0, 0).toHexString()}")
        it.recycle()
    }
Android-Entwickler
quelle