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.