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>

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;
}

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;
}

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;
}

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;
}

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
}

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);

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


1

Kotlin-Lösung:

    context.obtainStyledAttributes(TypedValue().data, intArrayOf(R.attr.colorAccent)).let {
        Log.d("AppLog", "color:${it.getColor(0, 0).toHexString()}")
        it.recycle()
    }
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.