user6694745 user6694745 - 4 months ago 17
Android Question

What does the "the returned color will be styled for the specified Context's theme" mean?

I recently noticed that a method

Context.getResources.getColor(int)


is deprecated since API 23.
One should instead use

ContextCompat.getColor(context, R.color.your_color);


The docs say about it:


int getColor (Context context, int id) Returns a color associated
with a particular resource ID Starting in M, the returned color will
be styled for the specified Context's theme.


But, what does it mean that a color will be styled for a particular theme. Isn't a color color? A constant? Predefined colors are used in themes. So how can it be styled?

Answer

From the docs for Resources - int getColor (int id, Resources.Theme theme):

Returns a themed color integer associated with a particular resource ID. If the resource holds a complex ColorStateList, then the default color from the set is returned.

So the resource id can be more than just a simple color, it could point to something like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
          android:color="@color/sample_focused" />
    <item android:state_pressed="true"
          android:state_enabled="false"
          android:color="@color/sample_disabled_pressed" />
    <item android:state_enabled="false"
          android:color="@color/sample_disabled_not_pressed" />
    <item android:color="@color/sample_default" />
 </selector>

in which case the color returned would be @color/sample_default.

But if you wanted to use attributes for the colors, something like this

    <item android:color="?attr/sample_default_color" />

you would need to access the attribute value within the theme in order to completely resolve the color value.

According to Alex Lockwood's blog post, these resources aren't actually attached to a theme, and if you call the old method with a color state list that uses attributes, an exception will be thrown. Before Marshmallow, you couldn't use attributes in color state lists due to this limitation.