getResources().getColor() is deprecated
It looks like the best approach is to use:
ContextCompat.getColor(context, R.color.color_name)
eg:
yourView.setBackgroundColor(ContextCompat.getColor(applicationContext,
R.color.colorAccent))
This will choose the Marshmallow two parameter method or the pre-Marshmallow method appropriately.
getResources().getColor() showing deprecated even after API check
Use this ContextCompat.getColor(context,R.color.your_color);
Why is getResources().getColor(int) deprecated?
Some complex colors like android.content.res.GradientColor
(which are used inside a VectorDrawable
) need a Theme in order to inflate the gradient, since you could have a definition like:
<gradient xmlns:android="http://schemas.android.com/apk/res/android">
<android:startColor="?android:attr/colorPrimary"/>
<android:endColor="?android:attr/colorControlActivated"/>
<android:type="linear"/>
</gradient>
getColor(int id) deprecated on Android 6.0 Marshmallow (API 23)
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.
getColor(int) is deprecated how i can use getColor(int,theme theme)
Use something as
ResourcesCompat.getColor(getResources(), R.color.red, null)
(Prior to API level 23 the theme will not be applied, so it may be null
.)
What's the use of `theme` in `context.getColor` ?
tl;dr
- If your min SDK is 23 you don't need the compat API for obtaining colors.
- If you don't use theme attribute references in colors and don't plan change, use
Context.getResources().getColor(int)
orgetColorStateList(int)
as you're used to. It's marked deprecated but functionally it's OK. - If you want to use theme attribute references in colors on API 23+ only, use
ContextCompat.getColorStateList(Context, int)
. - If you use AppCompat and want to be able to use theme attribute references on all versions of Android, use
AppCompatResources.getColorStateList(Context, int)
.
Starting API 23 ColorStateList
can contain theme attribute references, the same thing that's allowed in Drawable
since API 21.
Theme attributes are mostly used in color state lists obtained by getColorStateList
method as opposed to getColor
so I'll use that from now on. Most of what's mentioned applies to both variants.
Example:
res/color/my_csl.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="?attr/colorControlHighlight" android:alpha="?android:disabledAlpha"/>
<item android:color="?attr/colorControlHighlight"/>
</selector>
What's the purpose of the 'theme' parameter?
Theme is required to resolve theme attributes. Resources itself is not aware of any theme. Theme is provided by a context.
context.getColorStateList(R.color.my_csl);
is essentially a shortcut to
context.getResources().getColorStateList(R.color.my_csl, context.getTheme());
Both of these methods are part of public API so both of them were backported:
ContextCompat.getColorStateList(context, R.color.my_csl);
ResourcesCompat.getColorStateList(context.getResources(), R.color.my_csl, context.getTheme());
How is it used?
Typically it's as simple as this:
final int myColor = ContextCompat.getColorStateList(context, R.color.my_csl);
If you use AppCompat you might be better off with another option:
final int myColor = AppCompatResources.getColorStateList(context, R.color.my_csl);
Here's a comparison between these two options:
ContextCompat.getColorStateList
- Requires only
support-compat
support library - Backports only API - it will crash when trying to resolve theme attributes below API 23
- Requires only
AppCompatResources.getColorStateList
- Requires full
appcompat-v7
support library - Backports functionality - it will respect context theme even below API 23
- Requires full
ResourcesCompat.getColorStateList(int, Theme)
is API (not functional) backport of Resources.getColorStateList(int, Theme)
which is used internally by Context.getColorStateList(int)
on API 23+. In everyday use you won't be needing this method.
Why was the function deprecated anyway? It still seems safe to use for me...
The method was deprecated to migrate developers from the version that's not aware of themes to the theme-aware version of the method.
The theme-unaware method is still perfectly safe to use as long as you use it to obtain colors without theme attribute references, for example:
res/values/colors.xml
<resources>
<color name="my_cint">#f00</color>
</resources>
can be safely obtained by
context.getResources().getColor(R.color.my_cint);
What's the use of the support library function?
ContextCompat.getColorStateList(context, R.color.my_csl);
is literally this
public static final ColorStateList getColorStateList(Context context, @ColorRes int id) {
if (Build.VERSION.SDK_INT >= 23) {
return context.getColorStateList(id);
} else {
return context.getResources().getColorStateList(id);
}
}
The method exists so you don't have to write if-else everywhere. That's it.
On API 23+ it can use the context theme. Below API 23 it falls back to the old version that cannot resolve theme attributes.
ResourcesCompat.getColorStateList(int, Theme)
looks and works similarly, it ignores theme attributes (crashes when you use them) below API 23.
AppCompatResources.getColorStateList(Context, int)
will not crash and correctly resolve theme attributes on all versions of Android.
What about
ResourcesCompat#getColorStateList
?
You won't typically need this method.
It's a layer of abstraction. It's telling you that to resolve a color you don't need any god-object, any Context
. Resources
is just enough to resolve a color. BUT for Resources
to be able to resolve theme attributes you need to provide a Theme
. The fact that a Theme
can be obtained from a Context
is of no concern to Resources
. Resources
doesn't disclose or care that it itself came from some Context.getResources()
.
Can you [...] update about
getColor
too?
getColor
will resolve
<color>
resource as color integer<selector>
color state list resource as color integer of its default color
getColorStateList
will resolve
<color>
resource asColorStateList
with one color<selector>
CSL resource asColorStateList
with specified colors
Use the one that's required by consumer API.
There is no AppCompatResources.getColor(Context, int)
because there's little point in a color resource being defined as a theme attribute reference. If you ever need this AppCompatResources.getColorStateList(Context, int).getDefaultColor()
is the functional equivalent.
ContextCompat.getColor(Context, int)
and ResourcesCompat.getColor(Resources, int, Theme)
exist because they mirror the framework API. Their practical usefulness, as described above, is debatable.
I recommend reading the discussion below to grasp some of the elusive subtle differences.
Famous and old method getColor (int id) is deprecated. Api 23
Then finally i want to ask how to use (R.color.colorPrimary) without
any deprecation?
using ContextCompat.getColor(). E.g.
textView.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
From the doc
Returns a color associated with a particular resource ID Starting in
M, the returned color will be styled for the specified Context's
theme.
Related Topics
Android Vpnservice to Capture Packets Won't Capture Packets
Show and Hide a View With a Slide Up/Down Animation
Android.App Fragments VS. Android.Support.V4.App Using Viewpager
How to Change the New Tablayout Indicator Color and Height
How to Add Shortcut to Home Screen in Android Programmatically
Completely Transparent Status Bar and Navigation Bar on Lollipop
Simple Way to Do Dynamic But Square Layout
How to Get the Uuid of My Android Phone in an Application
Importing Google-Play-Services Lib into Intellij Idea 12 (And 13)
Implementing a Rich Text Editor in Android
How to Start Android Application Info Screen Programmatically
Select + Copy Text in a Textview
Is Using Serializable in Android Bad
Menuitemcompat.Getactionview Always Returns Null