Home » Android » android – Get color value programmatically when it's a reference (theme)

android – Get color value programmatically when it's a reference (theme)

Posted by: admin March 11, 2020 Leave a comment

Questions:

Consider this:

styles.xml

<style name="BlueTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <item name="theme_color">@color/theme_color_blue</item>
</style>

attrs.xml

<attr name="theme_color" format="reference" />

color.xml

<color name="theme_color_blue">#ff0071d3</color>

So the theme color is referenced by the theme. How can I get the theme_color (reference) programmatically? Normally I would use getResources().getColor() but not in this case because it’s referenced!

How to&Answers:

This should do the job:

TypedValue typedValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.theme_color, typedValue, true);
@ColorInt int color = typedValue.data;

Also make sure to apply the theme to your Activity before calling this code. Either use:

android:theme="@style/Theme.BlueTheme"

in your manifest or call (before you call setContentView(int)):

setTheme(R.style.Theme_BlueTheme)

in onCreate().

I’ve tested it with your values and it worked perfectly.

Answer:

To add to the accepted answer, if you’re using kotlin.

fun Context.getColorFromAttr(
    @AttrRes attrColor: Int,
    typedValue: TypedValue = TypedValue(),
    resolveRefs: Boolean = true
): Int {
    theme.resolveAttribute(attrColor, typedValue, resolveRefs)
    return typedValue.data
}

and then in your activity you can do

textView.setTextColor(getColorFromAttr(R.attr.color))

Answer:

This worked for me:

int[] attrs = {R.attr.my_attribute};
TypedArray ta = context.obtainStyledAttributes(attrs);
int color = ta.getResourceId(0, android.R.color.black);
ta.recycle();

if you want to get the hexstring out of it:

Integer.toHexString(color)

Answer:

If you want to get multiple colors you can use:

int[] attrs = {R.attr.customAttr, android.R.attr.textColorSecondary, 
        android.R.attr.textColorPrimaryInverse};
Resources.Theme theme = context.getTheme();
TypedArray ta = theme.obtainStyledAttributes(attrs);

int[] colors = new int[attrs.length];
for (int i = 0; i < attrs.length; i++) {
    colors[i] = ta.getColor(i, 0);
}

ta.recycle();

Answer:

Here’s a concise Java utility method that takes multiple attributes and return an array of color integers. 🙂

/**
 * @param context    Pass the activity context, not the application context
 * @param attrFields The attribute references to be resolved
 * @return int array of color values
 */
@ColorInt
static int[] getColorsFromAttrs(Context context, @AttrRes int... attrFields) {
    int length = attrFields.length;
    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();

    @ColorInt int[] colorValues = new int[length];

    for (int i = 0; i < length; ++i) {
        @AttrRes int attr = attrFields[i];
        theme.resolveAttribute(attr, typedValue, true);
        colorValues[i] = typedValue.data;
    }

    return colorValues;
}

Answer:

For those who are looking for reference to a drawable you should use false in resolveRefs

theme.resolveAttribute(R.attr.some_drawable, typedValue, **false**);