752

The Resources.getColor(int id) method has been deprecated.

@ColorInt
@Deprecated
public int getColor(@ColorRes int id) throws NotFoundException {
    return getColor(id, null);
}

What should I do?

Johnny Five
  • 788
  • 1
  • 9
  • 27
araks
  • 38,550
  • 8
  • 32
  • 39
  • 33
    Use ContextCompat.getColor(context, R.color.color_name) – Ashokchakravarthi Nagarajan Mar 31 '16 at 04:56
  • With this method mentioned above: getColor(context, R.color.your_color); It is not clear how to get the "context". It won't work by just putting context there in my case, android studio 3.2. I find this works for me. .setTextColor(Color.RED). – Harry Apr 28 '19 at 16:33

13 Answers13

1413

Starting from Android Support Library 23,
a new getColor() method has been added to ContextCompat.

Its description from the official JavaDoc:

Returns a color associated with a particular resource ID

Starting in M, the returned color will be styled for the specified Context's theme.


So, just call:

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

You can check the ContextCompat.getColor() source code on GitHub.

Community
  • 1
  • 1
araks
  • 38,550
  • 8
  • 32
  • 39
  • 1
    This looks like the solution, but what are we supposed to do when we get an error "Should pass resolved color instead of resource id here"? As far as I can tell it's probably because Lint does not recognise the new API of the Support Library, so maybe just adding an annotation @SuppressWarnings("ResourceAsColor") is the way to go? I don't like it much though. – Stan Mar 15 '16 at 16:40
  • 1
    Hi @Stan, can you please provide the code snippet with the method call that triggers the "ResourceAsColor" Lint? – araks Mar 15 '16 at 17:02
  • "int color = ContextCompat.getColor(this, R.color.orange);" and then "span = new ForegroundColorSpan(color);". The word that gets underlined in red is "color" where I pass it to "new ForegroundColorSpan()". – Stan Mar 16 '16 at 11:03
  • @Stan I've just tried on my PC and it isn't giving off that warning. I'm using Android Studio 2.1 Preview 1 and Support Library 23.2.1. What's your setup? – araks Mar 16 '16 at 11:09
  • I'm using the same Android Studio, tried Support library 23.1.1 and 23.2.1. Additionally, I'm building on Mac, Android Studio runs with jdk1.7.0_79.jdk for the IDE itself, and also for building the project (by default it uses Java 1.6 for the IDE on Mac). I don't know the version of Lint or how to check it but I'm starting to think the reason is elsewhere. – Stan Mar 16 '16 at 13:03
  • @Stan same setup here. Don't know what else it might be, sorry! – araks Mar 16 '16 at 14:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/106481/discussion-between-stan-and-araks). – Stan Mar 16 '16 at 14:56
  • Inspecting the ContextCompat.getColor(...), you don't need to check programmatically for the Build version because that method already does for you. – Monica Aspiras Labbao Aug 15 '16 at 09:45
  • @MonicaLabbao If you read carefully the answer you'll see that the code that checks the build version is actually the ContextCompat source code...! – araks Aug 15 '16 at 09:49
  • @araks yeah that's what I said. That's what I saw when I inspected the source code. Anyway, let's join the chat if you want to discuss this. – Monica Aspiras Labbao Aug 15 '16 at 10:53
  • 1
    @MonicaLabbao oh... sorry, I misunderstood your comment! :) – araks Aug 15 '16 at 12:28
  • This isn't working for me. How do you use this new way to get the color if your app supports lower than API 23? The `getContext()` in my code is underlined in red in Android Studio because the lowest API my app supports is 16. – ShadowGod Oct 09 '16 at 04:57
  • @ShadowGod this works all the way down to API 4, if your getContext() is underlined in red then there's another problem... What does the IDE suggest you if you leave the mouse over the error for a couple of seconds? – araks Oct 09 '16 at 06:05
  • @araks thanks, I got it working, it's because it was in a fragment – ShadowGod Oct 09 '16 at 06:11
  • @ShadowGod I also got a red line, I guess I'm missing an import? How did you get rid of it? – not2qubit Nov 14 '16 at 07:38
  • 3
    ContextCompatApi23 this mark error supossed you reference ContextCompat – Webserveis Nov 25 '16 at 19:45
  • For those who don't want to use ContextCompat simply use `Context.getColor(int id)`. – Muhammad Babar Jun 30 '17 at 06:31
  • But this ContextCompat returns a color id right? So places where a Color is expected are we suppose to generate the color like new Color(ContextCompat.getColor(context, R.color.your_color)) ? – Midhun Kumar Jan 22 '19 at 11:15
  • I don't get what's the use of the "theme". Are there any examples? – android developer Mar 03 '19 at 00:46
515

tl;dr:

ContextCompat.getColor(context, R.color.my_color)

Explanation:

You will need to use ContextCompat.getColor(), which is part of the Support V4 Library (it will work for all the previous APIs).

ContextCompat.getColor(context, R.color.my_color)

If you don't already use the Support Library, you will need to add the following line to the dependencies array inside your app build.gradle (note: it's optional if you already use the appcompat (V7) library):

compile 'com.android.support:support-v4:23.0.0' # or any version above

If you care about themes, the documentation specifies that:

Starting in M, the returned color will be styled for the specified Context's theme

Rafael Tavares
  • 1,417
  • 1
  • 14
  • 27
Melvin
  • 7,291
  • 3
  • 20
  • 26
  • 4
    This should be the selected as correct answer. Because in the given link of Android Docs, it say "_Starting in `M`, the returned color will be styled for the specified Context's theme._" – Bugs Happen Aug 23 '15 at 17:33
  • 1
    compile 'com.android.support:appcompat-v7:23.0.1' – G O'Rilla Sep 26 '15 at 13:55
  • @G O'Rilla As you can see in the documentation, the `ContextCompat` class comes from SupportV4. AppcompatV7 works too as it relies on SupportV4. As they say on the [Support Library documentation](https://developer.android.com/tools/support-library/features.html#v7-appcompat), `This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.`. So it makes sense not to put `AppcompatV7` in the answer. – Melvin Sep 26 '15 at 21:06
  • 1
    Thanks @Melvin, here is my example if of use: int colorTwitterBlue = ContextCompat.getColor(this, R.color.color_twitter_blue); composeTweetAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(colorTwitterBlue); composeTweetAlertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(colorTwitterBlue); – Lara Ruffle Coles Apr 27 '16 at 20:48
  • Whoever downvoted this answer, the least you can do is at least write a comment on what's the issue is… – Melvin Sep 15 '16 at 18:33
  • 1
    @Melvin. What exactly does it mean the the 'color will be styled to the specified Context's theme'. Sounds like one can define different colors for the same color id depending on the theme. How is this done exactly? – RobertoCuba Feb 14 '17 at 21:43
  • What's the use of the theme, though? – android developer Dec 24 '17 at 13:49
50

I don't want to include the Support library just for getColor, so I'm using something like

public static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return context.getColor(id);
    } else {
        //noinspection deprecation
        return context.getResources().getColor(id);
    }
}

I guess the code should work just fine, and the deprecated getColor cannot disappear from API < 23.

And this is what I'm using in Kotlin:

/**
 * Returns a color associated with a particular resource ID.
 *
 * Wrapper around the deprecated [Resources.getColor][android.content.res.Resources.getColor].
 */
@Suppress("DEPRECATION")
@ColorInt
fun getColorHelper(context: Context, @ColorRes id: Int) =
    if (Build.VERSION.SDK_INT >= 23) context.getColor(id) else context.resources.getColor(id);
Alex Vang
  • 4,365
  • 3
  • 34
  • 54
  • 4
    Looking at the source code, this is exactly how the support library does it. I target API >= 21 so I don't want to include a full jar for these few lines. Note that you can suppress the warning in Android Studio by adding "//noinspection deprecation" above the deprecated call. And use an Activity context, not an Application context, or you might lose theme information. – personne3000 Dec 22 '15 at 04:52
  • 2
    This should be the correct answer, although support library can be more future proof choice, I do agree that if this is the only reason you include the support library for, you better off including these couple of lines. – anthonymonori Nov 06 '16 at 17:40
30

In Android Marshmallow many methods are deprecated.

For example, to get color use

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

Also to get drawable use

ContextCompat.getDrawable(context, R.drawable.drawble_name);
Marko
  • 19,347
  • 13
  • 45
  • 61
  • 3
    where does the variable context come from? do i have to initialize it? I can't get it to work. To me it seem like Androind has a long way to go; it blows my f mind how much I am struggling to get a f color from a xml resource!! Wow – Caio Mar Oct 11 '17 at 22:34
30

For all the Kotlin users out there:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}
halfer
  • 18,701
  • 13
  • 79
  • 158
Paul Spiesberger
  • 4,334
  • 1
  • 37
  • 47
  • Actually should be `val color = ContextCompat.getColor(context, R.color.colorPrimary)`. The variable "it" could be anything, but it needs to be a __Context__. – SMBiggs Oct 28 '19 at 01:18
  • `it` is in this case the `context`, since I use `context?.let {` to check if the `context` is not null. The function `getColor()` only accepts a non-null context. Read more here about `let` and how to use it: https://kotlinlang.org/docs/reference/scope-functions.html#let – Paul Spiesberger Oct 28 '19 at 08:33
6

In Kotlin, you can do:

ContextCompat.getColor(requireContext(), R.color.stage_hls_fallback_snackbar)

if requireContext() is accessible from where you are calling the function. I was getting an error when trying

ContextCompat.getColor(context, R.color.stage_hls_fallback_snackbar)
Jamie
  • 129
  • 1
  • 7
4

In Your RecyclerView in Kotlin

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(t: YourObject, listener: OnItemClickListener.YourObjectListener) = with(itemView) {
        textViewcolor.setTextColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary))
        textViewcolor.text = t.name
    }
}
Irvin Joao
  • 191
  • 1
  • 3
2

If your current min. API level is 23, you can simply use getColor() like we are using to get string resources by getString():

//example
textView.setTextColor(getColor(R.color.green));
// if `Context` is not available, use with context.getColor()

You can constraint for API Levels below 23:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

but to keep it simple, you can do like below as accepted answer:

textView.setTextColor(ContextCompat.getColor(context, R.color.green))

From Resources.

From ContextCompat AndroidX.

From ContextCompat Support

Blasanka
  • 14,208
  • 6
  • 76
  • 90
1

Use the getColor(Resources, int, Theme) method of the ResourcesCompat from the Android Support Library.

int white = ResourcesCompat.getColor(getResources(), R.color.white, null);

I think it reflect better your question than the getColor(Context, int) of the ContextCompat since you ask about Resources. Prior to API level 23, the theme will not be applied and the method calls through to getColor(int) but you'll not have the deprecated warning. The theme also may be null.

android developer
  • 106,412
  • 122
  • 641
  • 1,128
Pedro
  • 391
  • 1
  • 8
  • 1
    If you pass null as Theme argument, the returned color will NOT be styled for the current theme. So it might be incorrect. – araks Nov 18 '15 at 21:11
  • @araks Isn't it the same as the deprecated call though? After all, you get the Resources instance in both cases, and not the Context. – android developer Feb 08 '21 at 07:56
  • @androiddeveloper they've deprecated the call exactly for that reason: to avoid loading non themed resources. If you pass null you invalidate all the code migration effort to fix this deprecation and expose yourself to the risk of loading non themed resources (mainly drawables) without any clear indication on why they're not working as intended. So you should alway provide a Theme instance from your current Activity/Fragment or use the ContextCompat.get* methods. – araks Feb 09 '21 at 09:26
  • @araks You mean the cases that drawables have "?attr/" ? – android developer Feb 09 '21 at 09:58
1

If you don't necessarily need the resources, use parseColor(String):
Color.parseColor("#cc0066")

N. Osil
  • 435
  • 5
  • 10
1

in activity used ContextCompat

ContextCompat.getColor(context, R.color.color_name)

in Adaper

private Context context;


context.getResources().getColor()
younes
  • 442
  • 3
  • 8
0

I got frustrated too. My need was very straightforward. All I wanted was the ARGB color from the resources, so I wrote a simple static method.

protected static int getARGBColor(Context c, int resId)
        throws Resources.NotFoundException {

    TypedValue color = new TypedValue();
    try {
        c.getResources().getValue(resId, color, true);
    }
    catch (Resources.NotFoundException e) {
        throw(new Resources.NotFoundException(
                  String.format("Failed to find color for resourse id 0x%08x",
                                resId)));
    }
    if (color.type != TYPE_INT_COLOR_ARGB8) {
        throw(new Resources.NotFoundException(
                  String.format(
                      "Resourse id 0x%08x is of type 0x%02d. Expected TYPE_INT_COLOR_ARGB8",
                      resId, color.type))
        );
    }
    return color.data;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
steven smith
  • 1,309
  • 12
  • 27
0

The best equivalent is using ContextCompat.getColor and ResourcesCompat.getColor . I made some extension functions for quick migration:

@ColorInt
fun Context.getColorCompat(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)

@ColorInt
fun Fragment.getColorCompat(@ColorRes colorRes: Int) = activity!!.getColorCompat(colorRes)

@ColorInt
fun Resources.getColorCompat(@ColorRes colorRes: Int) = ResourcesCompat.getColor(this, colorRes, null)
android developer
  • 106,412
  • 122
  • 641
  • 1,128