Como obter cores de destaque de forma programática?

87

Como alguém buscaria a cor de destaque definida em estilos, como abaixo, programaticamente?

    <item name="android:colorAccent">@color/material_green_500</item>
Jakob
fonte
3
Qualquer pessoa com voto negativo deve se sentir à vontade para postar suas opiniões em comentários ...
Jakob

Respostas:

130

Você pode obtê-lo do tema atual desta forma:

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
fonte
E sobre a versão de suporte?
DariusL
4
Esta é a versão de suporte.
rciovati
podemos definir string RGB em colorPrimary em styles.xml ou colors.xml ??
Tanveer Bulsari
2
Isso está retornando um número negativo para mim. Essa ainda é a maneira válida de obter a cor de destaque?
Naveed
1
A que typedValue.data faz referência?
GPack de
45

Isso funcionou para mim também:

public static int getThemeAccentColor (final Context context) {
    final TypedValue value = new TypedValue ();
    context.getTheme ().resolveAttribute (R.attr.colorAccent, value, true);
    return value.data;
}
copolii
fonte
Eu tenho o mesmo problema também nesta solução, valor negativo, e cai :(
batsheva
2
O valor negativo está bem. É uma cor!
copolii
mas minha aplicação desmorona com eroor nenhum recurso encontrado ... isso não acontece quando coloco uma cor normal! portanto, o valor não é bom
batsheva
Então, de onde vem o valor negativo se o recurso não for encontrado? Tudo o que estou dizendo é que 0xff2506ac (por exemplo) é um número negativo e um valor de cor válido.
copolii
2
O valor negativo que você obtém é a cor real, não a identificação do recurso. Não o use como um id de recurso.
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
fonte
2
Esta é a única resposta que não depende da importação da classe R do aplicativo, que é ideal para a construção de visualizações personalizadas.
Allan Veloso
12

Para aqueles que usam Kotlin

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

Eu tenho um método estático em uma classe de utils para obter as cores do tema atual. Na maioria das vezes, é colorPrimary, colorPrimaryDark e accentColor, mas você pode obter muito mais.

@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
fonte
7

Aqui está minha opinião sobre isso:

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

Uso:

    String windowBackgroundHex = getThemeColorInHex(this, "windowBackground", android.R.attr.windowBackground);
    String primaryColorHex = getThemeColorInHex(this, "colorPrimary", R.attr.colorPrimary);
Esdras Lopez
fonte
2
O String.format()ajuda a explicar como converter o valor inteiro negativo em uma string hexadecimal.
Sr. IDE
1
Esta é uma solução muito melhor / genérica do que a resposta aceita para esta pergunta!
Nilesh Pawar
1

Solução Kotlin:

    context.obtainStyledAttributes(TypedValue().data, intArrayOf(R.attr.colorAccent)).let {
        Log.d("AppLog", "color:${it.getColor(0, 0).toHexString()}")
        it.recycle()
    }
desenvolvedor android
fonte