784

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

What changed?

Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
Blodhgard
  • 8,480
  • 3
  • 18
  • 33
  • 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. – code monkey Mar 13 '15 at 20:26
  • 2
    ContextCompat.getDrawable(context, R.color.color_name) – Ashokchakravarthi Nagarajan Mar 31 '16 at 04:57
  • You can check out [**my blog post**](http://www.androiddesignpatterns.com/2016/08/contextcompat-getcolor-getdrawable.html) on this subject for a more thorough explanation about why both `Resources#getDrawable(int)` and `Resources#getColor(int)` were deprecated. – Alex Lockwood Aug 06 '16 at 19:07
  • 1
    Google should put quick-fixes for each deprecated function. I made a post about it here: https://code.google.com/p/android/issues/detail?id=219495 – android developer Aug 08 '16 at 07:58

16 Answers16

1173

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);
Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
araks
  • 38,550
  • 8
  • 32
  • 39
  • My app crashes using suggestion B. It doesn't like the call Drawable originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(), iconResId, null); – FractalBob May 29 '17 at 21:54
  • 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); – FractalBob May 29 '17 at 21:58
  • More precisely, the crash seems to be happening because my icon is a Vector drawable. – FractalBob May 29 '17 at 22:58
  • 1
    xamarin version: ResourcesCompat.GetDrawable(Resources, Resource.Drawable.name, null); – Brian Oct 23 '17 at 12:20
  • I add one further word to you,ContextCompat.getColor(context,color) also can help you... – BertKing Aug 21 '18 at 12:32
750

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).

Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
  • 8
    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. – code monkey Mar 13 '15 at 21:04
  • 9
    According to documentation, min API level 21 is required to use `getDrawable(int, Resources.Theme)`. – Prince May 04 '15 at 05:47
  • @Prince The method was added in API 21 but it wasn't deprecated until API 22. :) – Alex Lockwood Aug 26 '15 at 13:59
  • Android doc also recommends using [Context::getDrawable(int) method](https://developer.android.com/reference/android/content/res/Resources.html#getDrawable(int)) but since it was introduced only in API 21 seems that ContextCompat is the best choice. – goRGon Jan 12 '16 at 01:22
  • This answer does not work with .svg files, in versions older than API 21. There is a bug in the library. – Jorge Rodríguez Mar 17 '16 at 20:47
  • The suggestion fails when called from a Fragment: Drawable originalIcon = ContextCompat.getDrawable(getContext(), R.drawable.arrow_left); – FractalBob May 29 '17 at 22:20
145

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

Nagaraju Gajula
  • 520
  • 5
  • 12
vincent091
  • 2,245
  • 4
  • 15
  • 21
  • 2
    Thats depricated now too:https://plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM – Xyaren Mar 25 '15 at 10:16
  • see this link please : https://developer.android.com/reference/android/support/v4/content/ContextCompat.html#getDrawable(android.content.Context, int) – vincent091 May 18 '15 at 17:41
  • 2
    It doesn't say in [link](https://developer.android.com/reference/android/support/v4/content/res/ResourcesCompat.html) that `ResourcesCompat` is deprecated. It should work fine. – Jacob R Jun 09 '15 at 10:29
  • what to write in "your drawable" if i want to input images to a list view on clicking list items stored in drawable – 0x0001 Dec 05 '16 at 08:35
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));
}
Jorgesys
  • 114,263
  • 22
  • 306
  • 247
  • `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. :)" – Mark Cramer May 17 '16 at 18:16
5

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)
Deepak Ror
  • 1,408
  • 2
  • 15
  • 21
3

You can use

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

that's work for me

Dasser Basyouni
  • 2,614
  • 3
  • 20
  • 43
  • Using application context to load vector drawable crashes on pre lollipop. Any fix for this? – muthuraj Feb 09 '18 at 07:05
  • 1
    @muthuraj 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 ? – Dasser Basyouni Feb 24 '18 at 11:24
  • 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. – muthuraj Feb 24 '18 at 20:46
3

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.requireContext(), R.color.colorWhite)

or

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

Hope this will help you.Thanks.

Rahul Kushwaha
  • 1,146
  • 1
  • 9
  • 19
  • 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. – Pitos May 26 '20 at 05:55
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)));
Jay
  • 19
  • 1
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));
    }
}
Donald Duck
  • 6,488
  • 18
  • 59
  • 79
  • 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. – Donald Duck Feb 09 '17 at 15:06
1

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

context.getDrawable(R.drawable.your_drawable_name)

See docs

Adeel Ahmad
  • 829
  • 1
  • 9
  • 18
0

en api level 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));
ColdFire
  • 6,116
  • 6
  • 32
  • 50
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)
Farid Haq
  • 1,919
  • 15
  • 13
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

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);
Khalid Lakhani
  • 144
  • 1
  • 7
0

Try this

ContextCompat.getDrawable(getActivity(), R.drawable.drawable_resource_name);
Aalishan Ansari
  • 313
  • 1
  • 4
-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);
}
ColdFire
  • 6,116
  • 6
  • 32
  • 50