如何从资源文件创建可绘制对象?

319

我有一个图像资源res/drawable/test.png(R.drawable.test)。

我想把这个图像传递给一个接受Drawable参数的函数,例如mButton.setCompoundDrawables()

那么如何将图像资源转换为Drawable对象呢?

9个回答

620

你的Activity应该有getResources方法。请执行以下操作:

Drawable myIcon = getResources().getDrawable( R.drawable.icon );
从API版本21开始,该方法已被弃用,可以使用以下方法替换:
Drawable myIcon = AppCompatResources.getDrawable(context, R.drawable.icon);

如果您需要指定自定义主题,以下内容将应用它,但仅在API版本21或更高版本时才会生效:

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

2
如果您想在Activity类之外使用此功能,则必须找到其他方法来访问getResources()所在的上下文;该解答建议将其传递给构造函数 - rymo
56
自 API 版本 21 起,此方法已被弃用,您应该改为使用:Drawable drawable = ResourcesCompat.getDrawable(getResources(), page.getImageId(), null); - Boren
3
使用ContextCompat.getDrawable(this, R.drawable.icon)与之相同吗? - Zach
2
如果R.drawable.icon是矢量图,则以上建议似乎都不起作用。 - FractalBob
7
如果你正在使用矢量图形,请不要使用此方法。请改用AppCompatResources.getDrawable(context, R.drawable.icon)。该方法能够达到相同的效果,但更加兼容。 - Dhaval Patel
显示剩余5条评论

142

这段代码已被弃用:

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

请使用这个替代:

Drawable drawable = ContextCompat.getDrawable(getApplicationContext(),R.drawable.icon);

11
请注意,这将应用给定上下文中的主题。如果您想确保不使用任何主题,可以使用ResourcesCompat.getDrawable(getResources(), R.drawable.icon, null);(其中第三个参数是可选的Theme实例)。 - vaughandroid

23

getDrawable(int id)方法已在API 22中弃用。

相反,您应该使用getDrawable(int id, Resources.Theme theme)适用于API 21+。

代码看起来可能像这样。

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);
}

为什么不对每个 API 传递 null 呢?另外: 你确定 null 是最好的选择吗? - jonathanrz
1
直到API 21,才出现了getDrawable(int id, Resources.Theme theme)方法。 - Chris Stillwell
getResources().getDrawable(R.drawable.ic_warning_80dp, context?.theme) 请获取资源并使用上下文主题获取可绘制对象。 - Simon Featherstone

14

我只想补充一点,如果在使用getDrawable(...)时出现"已弃用(deprecated)"的消息,你应该改用支持库中的以下方法。

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

使用这种方法时,您不必使用getResources()。

这相当于执行类似以下操作:

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]);
}

这适用于早期和后期Lollipop版本。


5

无论是矢量图还是其他格式的图像,都可以从矢量资源中获取可绘制对象:

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

注意:
对于矢量图资源,ContextCompat.getDrawable(context, R.drawable.icon);会产生android.content.res.Resources$NotFoundException异常。


优秀的回答!! - Jim Andreas

4
如果你想要从图片所在的视图获取可绘制对象,
ivshowing.setBackgroundResource(R.drawable.one);

如果使用以下代码,则可得到null值,表示drawable为空...
   Drawable drawable = (Drawable) ivshowing.getDrawable();

如果您想从特定视图检索可绘制对象,则最好使用以下代码设置图像。

 ivshowing.setImageResource(R.drawable.one);

只有这样,可绘制对象才能被准确转换。

2
如果您正在从片段中继承,可以执行以下操作:
Drawable drawable = getActivity().getDrawable(R.drawable.icon)
"R.drawable.icon"是图标的资源ID。

这对我有用,Android Studio建议将其转换为requireActivity()!!.getDrawable(R.drawable.id)!!。 - erhun

2

您必须通过兼容的方式获取它,其他方法已被弃用:

Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.my_drawable, null);

0
在 Kotlin 中,你可以这样做:
binding.floatingActionButton.setImageDrawable(
            AppCompatResources.getDrawable(this, android.R.drawable.ic_delete))

binding 是根视图并且它引用了 Context 时,你需要进行导入

import androidx.appcompat.content.res.AppCompatResources

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接