Android getResources().getDrawable() deprecated API 22
Asked Answered
P

16

856

With new android API 22 getResources().getDrawable() is now deprecated. Now the best approach is to use only getDrawable().

What changed?

Promontory answered 13/3, 2015 at 20:5 Comment(4)
Could you specify your question? It is right that the method getDrawable (int id) of the class Resources is deprecated. You should now use the method getDrawable (int id, Resources.Theme theme) with the new theme parameter.Aut
ContextCompat.getDrawable(context, R.color.color_name)Pluri
You can check out my blog post on this subject for a more thorough explanation about why both Resources#getDrawable(int) and Resources#getColor(int) were deprecated.Todtoday
Google should put quick-fixes for each deprecated function. I made a post about it here: code.google.com/p/android/issues/detail?id=219495Palaearctic
E
1307

You have some options to handle this deprecation the right (and future proof) way, depending on which kind of drawable you are loading:


A) drawables with theme attributes

ContextCompat.getDrawable(getActivity(), R.drawable.name);

You'll obtain a styled Drawable as your Activity theme instructs. This is probably what you need.


B) drawables without theme attributes

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

You'll get your unstyled drawable the old way. Please note: ResourcesCompat.getDrawable() is not deprecated!


EXTRA) drawables with theme attributes from another theme

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
Extensible answered 19/3, 2015 at 14:13 Comment(7)
My app crashes using suggestion B. It doesn't like the call Drawable originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(), iconResId, null);Tyrrell
I declare it this way: public static void setImageButtonEnabled(Context ctxt, boolean enabled, ImageButton item, int iconResId) { item.setEnabled(enabled); Drawable originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(), iconResId, null); Drawable icon = enabled ? originalIcon : convertDrawableToGrayScale(originalIcon); item.setImageDrawable(icon); } and call it like this: Utility.setImageButtonEnabled(getContext(), false, back, R.drawable.arrow_left);Tyrrell
More precisely, the crash seems to be happening because my icon is a Vector drawable.Tyrrell
xamarin version: ResourcesCompat.GetDrawable(Resources, Resource.Drawable.name, null);Gablet
I add one further word to you,ContextCompat.getColor(context,color) also can help you...Goddamned
Using this in an adapter like this - ResourcesCompat.getDrawable(viewGroup.getContext().getResources(), R.drawable.touch_feedback, null);Cargian
Do deprecated it and replaced it with something worse. I'm not calling getResources every time someone clicks on a button. That's woeful.Sexism
T
759

Edit: see my blog post on the subject for a more complete explanation


You should use the following code from the support library instead:

ContextCompat.getDrawable(context, R.drawable.***)

Using this method is equivalent to calling:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

As of API 21, you should use the getDrawable(int, Theme) method instead of getDrawable(int), as it allows you to fetch a drawable object associated with a particular resource ID for the given screen density/theme. Calling the deprecated getDrawable(int) method is equivalent to calling getDrawable(int, null).

Todtoday answered 13/3, 2015 at 20:32 Comment(6)
I think that the OP also refers to the getDrawable (int id) method of the Context class. This is the same as getResources().getDrawable(id, getTheme()); and also uses the new API.Aut
According to documentation, min API level 21 is required to use getDrawable(int, Resources.Theme).Probst
@Probst The method was added in API 21 but it wasn't deprecated until API 22. :)Todtoday
Android doc also recommends using Context::getDrawable(int) method but since it was introduced only in API 21 seems that ContextCompat is the best choice.Tubular
This answer does not work with .svg files, in versions older than API 21. There is a bug in the library.Latrishalatry
The suggestion fails when called from a Fragment: Drawable originalIcon = ContextCompat.getDrawable(getContext(), R.drawable.arrow_left);Tyrrell
R
150

Replace this line : getResources().getDrawable(R.drawable.your_drawable)

with ResourcesCompat.getDrawable(getResources(), R.drawable.your_drawable, null)

EDIT

ResourcesCompat is also deprecated now. But you can use this:

ContextCompat.getDrawable(this, R.drawable.your_drawable) (Here this is the context)

for more details follow this link: ContextCompat

Referendum answered 18/3, 2015 at 8:32 Comment(4)
Thats depricated now too:plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBMOverlook
see this link please : developer.android.com/reference/android/support/v4/content/…, int)Referendum
It doesn't say in link that ResourcesCompat is deprecated. It should work fine.Interjoin
what to write in "your drawable" if i want to input images to a list view on clicking list items stored in drawableElevator
H
29

getResources().getDrawable() was deprecated in API level 22. Now we must add the theme:

getDrawable (int id, Resources.Theme theme) (Added in API level 21)

This is an example:

myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));

This is an example how to validate for later versions:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));
   } else { 
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage));
}
Heterozygote answered 29/9, 2015 at 21:25 Comment(1)
Build.VERSION_CODES.LOLLIPOP is API 21, so shouldn't this be if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) or if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Never mind. From below "The method was added in API 21 but it wasn't deprecated until API 22. :)"Charmeuse
S
13

Try this

ContextCompat.getDrawable(getActivity(), R.drawable.drawable_resource_name);
Schleicher answered 3/5, 2021 at 9:52 Comment(0)
R
10

getDrawable(int drawable) is deprecated in API level 22. For reference see this link.

Now to resolve this problem we have to pass a new constructer along with id like as :-

getDrawable(int id, Resources.Theme theme)

For Solutions Do like this:-

In Java:-

ContextCompat.getDrawable(getActivity(), R.drawable.name);   

or

 imgProfile.setImageDrawable(getResources().getDrawable(R.drawable.img_prof, getApplicationContext().getTheme()));

In Kotlin :-

rel_week.background=ContextCompat.getDrawable(this, R.color.colorWhite)
 or,
rel_week.background=ContextCompat.getDrawable(requireContext(), R.color.colorWhite)
)

or

 rel_day.background=resources.getDrawable(R.drawable.ic_home, context?.theme)

Hope this will help you.Thanks.

Roose answered 11/10, 2019 at 5:21 Comment(3)
It is worth mentioning, that getDrawable(DrawableRes int id, Theme theme) can throw an exception if the resource is not found while, getDrawable(Context context, int id) is nullable, so it has to be returned with Drawable? in Kotlin.Kendo
This formatting is utterly horrible and the code in Kotlin do not compileSuperscription
@J.Doe yes , this may be old code . I will update the new answer.Roose
F
8

In Kotlin you can use extension

fun Context.getMyDrawable(id : Int) : Drawable?{

    return  ContextCompat.getDrawable(this, id)
}

then use like

context.getMyDrawable(R.drawable.my_icon)
Fatherless answered 12/11, 2019 at 4:42 Comment(0)
S
3

You can use

ContextCompat.getDrawable(getApplicationContext(),R.drawable.example);

that's work for me

Satisfy answered 26/12, 2016 at 4:36 Comment(3)
Using application context to load vector drawable crashes on pre lollipop. Any fix for this?Silvery
@Silvery I don't remember my testing for the code with lollipop case, but you can try getActivity() or getResources() instead then, does that goes well with your code ?Satisfy
I'm using MVVM pattern and I need to inflate drawables inside ViewModels which don't have activity context. It only has application context. That's what my issue is.Silvery
E
1

Just an example of how I fixed the problem in an array to load a listView, hope it helps.

 mItems = new ArrayList<ListViewItem>();
//    Resources resources = getResources();

//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.az_lgo), getString(R.string.st_az), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.ca_lgo), getString(R.string.st_ca), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.co_lgo), getString(R.string.st_co), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.az_lgo, null), getString(R.string.st_az), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.ca_lgo, null), getString(R.string.st_ca), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.co_lgo, null), getString(R.string.st_co), getString(R.string.all_nums)));
Epilate answered 12/1, 2016 at 17:40 Comment(0)
V
1

Try this:

public static List<ProductActivity> getCatalog(Resources res){
    if(catalog == null) {
        catalog.add(new Product("Dead or Alive", res
                .getDrawable(R.drawable.product_salmon),
                "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
        catalog.add(new Product("Switch", res
                .getDrawable(R.drawable.switchbook),
                "Switch by Chip Heath and Dan Heath", 24.99));
        catalog.add(new Product("Watchmen", res
                .getDrawable(R.drawable.watchmen),
                "Watchmen by Alan Moore and Dave Gibbons", 14.99));
    }
}
Vivacity answered 9/2, 2017 at 14:47 Comment(1)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Monoatomic
S
1

If you are targeting SDK > 21 (lollipop or 5.0) use

context.getDrawable(R.drawable.your_drawable_name)

See docs

Subordinary answered 24/9, 2018 at 20:21 Comment(0)
S
0

en api level 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));
Scrambler answered 20/1, 2018 at 16:46 Comment(1)
You should provide a bit more context around your answer.Halfhardy
T
0

Now you need to implement like this

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
        //
    } else {
        //
    }

Following single line of code is enough, everything will take care by ContextCompat.getDrawable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)
Turoff answered 1/3, 2019 at 4:20 Comment(0)
K
0

For some who still got this issue to solve even after applying the suggestion of this thread(i used to be one like that) add this line on your Application class, onCreate() method

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

As suggested here and here sometimes this is required to access vectors from resources especially when you're dealing with menu items, etc

Kingpin answered 30/10, 2019 at 8:24 Comment(0)
C
0

In case you need drawable from other app targeting SDK 23 and up

PackageManager manager = getApplicationContext().getPackageManager();
Resources resources = null;
try {
    resources = manager.getResourcesForApplication("com.anyapp");
    } 
catch (PackageManager.NameNotFoundException e) {
   e.printStackTrace();
   }
assert resources != null;
Drawable notiIcon = ResourcesCompat.getDrawable(resources, current.iconId/* drawable resource id */, null);
Corvine answered 28/2, 2021 at 5:41 Comment(0)
I
-2

Build.VERSION_CODES.LOLLIPOP should now be changed to BuildVersionCodes.Lollipop i.e:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}
Iron answered 2/12, 2015 at 1:6 Comment(1)
Isn't BuildVersionCodes a class specific to Xamarin?Galbraith

© 2022 - 2024 — McMap. All rights reserved.