317

I have an image res/drawable/test.png (R.drawable.test).
I want to pass this image to a function which accepts Drawable, e.g. mButton.setCompoundDrawables().

So how can I convert an image resource to a Drawable?

nnnmmm
  • 7,964
  • 4
  • 22
  • 41
User7723337
  • 11,857
  • 27
  • 101
  • 182

9 Answers9

618

Your Activity should have the method getResources. Do:

Drawable myIcon = getResources().getDrawable( R.drawable.icon );


As of API version 21 this method is deprecated and can be replaced with:

Drawable myIcon = AppCompatResources.getDrawable(context, R.drawable.icon);

If you need to specify a custom theme, the following will apply it, but only if API is version 21 or greater:

Drawable myIcon =  ResourcesCompat.getDrawable(getResources(), R.drawable.icon, theme);
Jems
  • 11,560
  • 1
  • 29
  • 35
  • Do you need to add something else to the manifest for instance? I created an empty project with only this line of code in onCreate and I get Resources$NotFoundException. The project came with icon.png in hdpi, ldpi and mdpi map. – Vincent Mar 29 '11 at 14:18
  • 2
    If you happen to want this outside of an Activity class, you'll have to find some other way to reach the Context where getResources() lives; [this answer recommends passing it into the constructor](http://stackoverflow.com/a/6214567/404960) – rymo Jun 30 '14 at 20:39
  • 56
    As of API version 21 this method is deprecated and you should be replaced by: Drawable drawable = ResourcesCompat.getDrawable(getResources(), page.getImageId(), null); – Boren Apr 14 '15 at 23:07
  • 3
    @Boren is it the same as to use ContextCompat.getDrawable(this, R.drawable.icon);? – Zach Sep 01 '16 at 17:57
  • @Boren This is also OK: Drawable myIcon = getResources().getDrawable( R.drawable.icon, null ); – Lev Jan 11 '17 at 08:20
  • 2
    None of the above suggestions seem to work if R.drawable.icon is a Vector drawable. – FractalBob May 29 '17 at 22:57
  • 7
    DON'T USE THIS IF YOU ARE USING VECTOR DRAWABLE. Use AppCompatResources.getDrawable(context, R.drawable.icon ) instead. – Dhaval Patel Oct 03 '18 at 04:37
  • getDrawable() is deprecated as of Lollipop. – hopia Nov 20 '18 at 18:42
  • @DhavalPatel May you please explain why to use `AppCompatResources.getDrawable(context, R.drawable.icon ) ` – Kwnstantinos Nikoloutsos Sep 24 '20 at 20:49
  • @KwnstantinosNikoloutsos It will throw android.content.res.Resources$NotFoundException for vector resources. – Dhaval Patel Sep 25 '20 at 04:27
142

This code is deprecated:

Drawable drawable = getResources().getDrawable( R.drawable.icon );

Use this instead:

Drawable drawable = ContextCompat.getDrawable(getApplicationContext(),R.drawable.icon);
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
daniel kilinskas
  • 3,538
  • 3
  • 16
  • 10
  • 11
    Be aware that this will apply the theme from the given context. If you want to ensure no theme is used, you can use `ResourcesCompat.getDrawable(getResources(), R.drawable.icon, null);` (where the 3rd param is an optional Theme instance). – vaughandroid Mar 31 '16 at 07:18
23

The getDrawable (int id) method is deprecated as of API 22.

Instead you should use the getDrawable (int id, Resources.Theme theme) for API 21+

Code would look something like this.

Drawable myDrawable;
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
    myDrawable = context.getResources().getDrawable(id, context.getTheme());
} else {
    myDrawable = context.getResources().getDrawable(id);
}
Lino
  • 5,084
  • 3
  • 21
  • 39
Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77
14

I would just like to add that if you are getting "deprecated" message when using getDrawable(...) you should use the following method from the support library instead.

ContextCompat.getDrawable(getContext(),R.drawable.[name])

You do not have to use getResources() when using this method.

This is equivalent to doing something like

Drawable mDrawable;
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
    mDrawable = ContextCompat.getDrawable(getContext(),R.drawable.[name]);
} else {
    mDrawable = getResources().getDrawable(R.id.[name]);
}

This works on both pre and post Lollipop versions.

Micer
  • 8,731
  • 3
  • 79
  • 73
Sameer Khanal
  • 1,199
  • 12
  • 11
5

Get Drawable from vector resource irrespective of, whether its vector or not:

AppCompatResources.getDrawable(context, R.drawable.icon);

Note:
ContextCompat.getDrawable(context, R.drawable.icon); will produce android.content.res.Resources$NotFoundException for vector resource.

Dhaval Patel
  • 10,119
  • 5
  • 43
  • 46
4

If you are trying to get the drawable from the view where the image is set as,

ivshowing.setBackgroundResource(R.drawable.one);

then the drawable will return only null value with the following code...

   Drawable drawable = (Drawable) ivshowing.getDrawable();

So, it's better to set the image with the following code, if you wanna retrieve the drawable from a particular view.

 ivshowing.setImageResource(R.drawable.one);

only then the drawable will we converted exactly.

Exceptional
  • 2,994
  • 1
  • 18
  • 25
2

If you are inheriting from a fragment you can do:

Drawable drawable = getActivity().getDrawable(R.drawable.icon)

vorwerg-ni
  • 157
  • 1
  • 5
  • That's worked for me, after Android Studio suggestion it converts to requireActivity()!!.getDrawable(R.drawable.id) – erhun Jul 28 '20 at 07:36
2

You must get it via compatible way, others are deprecated:

Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.my_drawable, null);
Samir Alakbarov
  • 1,120
  • 11
  • 21
0

In Kotlin you can do like this:

binding.floatingActionButton.setImageDrawable(
            AppCompatResources.getDrawable(this, android.R.drawable.ic_delete))

Where binding is a root View and this refer to Context, You need import

import androidx.appcompat.content.res.AppCompatResources
Mori
  • 2,653
  • 18
  • 24