Android getResources()。getDrawable()已弃用API 22


698

getResources().getDrawable()现在不推荐使用新的android API 22 。现在最好的方法是只使用getDrawable()

发生了什么变化?


您能指定您的问题吗?正确,getDrawable (int id)该类的方法Resources已被弃用。现在,您应该使用getDrawable (int id, Resources.Theme theme)带有新主题参数的方法。
代码猴子

1
ContextCompat.getDrawable(context,R.color.color_name)
Ashokchakravarthi Nagarajan

您可以查看关于此主题的博客文章,以更全面地解释为什么Resources#getDrawable(int)Resources#getColor(int)不推荐使用。
亚历克斯·洛克伍德

1
Google应该为每个不推荐使用的功能添加快速修复程序。我在这里发表了一篇关于它的文章:code.google.com/p/android/issues/detail?id=219495
android开发者

Answers:


1026

您有一些选择来以正确的方式(以及将来的证明)来处理这种弃用,这取决于您要加载的绘图类型:


A)具有主题属性的可绘制对象

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

您将按照Activity主题的指示获得样式化的Drawable。这可能就是您所需要的。


B)没有主题属性的绘画

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

您将以旧方式获得未样式化的可绘制对象。请注意:ResourcesCompat.getDrawable()不是过时!


具有其他主题的主题属性的EXTRA)可绘制对象

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

我的应用程序使用建议B崩溃。它不喜欢调用Drawable originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(),iconResId,null);
FractalBob

我这样声明:public static void setImageButtonEnabled(Context ctxt,boolean enabled,ImageButton item,int iconResId){item.setEnabled(enabled); Drawable originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(),iconResId,null); 可绘制图标=已启用?originalIcon:convertDrawableToGrayScale(originalIcon); item.setImageDrawable(icon); },然后这样调用:Utility.setImageButtonEnabled(getContext(),false,back,R.drawable.arrow_left);
FractalBob

更确切地说,崩溃似乎正在发生,因为我的图标是Vector可绘制的。
FractalBob

1
xamarin版本:ResourcesCompat.GetDrawable(Resources,Resource.Drawable.name,null);
布赖恩

再给

746

编辑:有关此主题的更多信息,请参见我的博客文章


您应该改用支持库中的以下代码:

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

使用此方法等效于调用:

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

从API 21开始,您应该使用getDrawable(int, Theme)方法而不是getDrawable(int),因为它允许您针对给定的屏幕密度/主题获取与特定资源ID关联的可绘制对象。调用不推荐使用的getDrawable(int)方法等同于调用getDrawable(int, null)


8
我认为OP也指getDrawable (int id)的是Context类的方法。这和getResources().getDrawable(id, getTheme());与新API,也使用新API。
代码猴子

9
根据文档,必须使用最低API级别21 getDrawable(int, Resources.Theme)
王子

@Prince该方法是在API 21中添加的,但是直到API 22才被弃用。:)
Alex Lockwood

Android文档还建议使用Context :: getDrawable(int)方法,但是由于它仅在API 21中引入,因此ContextCompat似乎是最佳选择。
goRGon

在API 21之前的版本中,此答案不适用于.svg文件。库中存在错误。
豪尔赫·罗德里格斯

141

替换此行: getResources().getDrawable(R.drawable.your_drawable)

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

编辑

ResourcesCompat现在也已弃用。但是您可以使用以下命令:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(这里this是上下文)

有关更多详细信息,请单击此链接:ContextCompat


2
多数民众赞成在现在也是如此:plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren 2015年


2
它并不表示已弃用的链接ResourcesCompat。它应该工作正常。
Jacob R

如果我要在单击存储在drawable中的列表项时将图像输入到列表视图中,应在“您的drawable”中写入什么内容
0x0001

29

getResources().getDrawable() 在API级别22中已弃用。现在我们必须添加主题:

getDrawable(int id,Resources.Theme主题) (在API级别21中添加)

这是一个例子:

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

这是一个如何验证更高版本的示例:

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

Build.VERSION_CODES.LOLLIPOP is API 21,所以应该不是这个是if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)?没关系。从下面开始:“该方法已添加到API 21中,但直到API 22才被弃用。:)”
Mark Cramer,

2

您可以使用

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

那对我有用


使用应用程序上下文在矢量棒棒糖上加载矢量可绘制崩溃。有什么解决办法吗?
muthuraj

1
@muthuraj我不记得我用棒棒糖案例测试过代码,但是您可以尝试使用getActivity()或getResources()代替,这对您的代码是否很好?
Dasser Basyouni

我正在使用MVVM模式,并且需要在没有活动上下文的ViewModels内部填充可绘制对象。它仅具有应用程序上下文。那就是我的问题。
muthuraj

1

这只是我如何解决数组加载listView问题的示例,希望对您有所帮助。

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

1

尝试这个:

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

尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。
唐老鸭


1

API级别22中不推荐使用getDrawable(int drawable)。有关参考,请参见此链接

现在要解决此问题,我们必须传递一个新的构造函数以及id,如:-

getDrawable(int id, Resources.Theme theme)

对于解决方案,请执行以下操作:-

在Java中:

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

要么

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

在科特林:-

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

要么

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

希望这会对您有所帮助。


值得一提的是,如果找不到资源,而getDrawable(Context context,int id)是可为空的,则getDrawable(DrawableRes int id,Theme theme)会引发异常,因此必须使用Drawable返回它吗?在科特林。
皮托斯


0

现在您需要像这样实现

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

只需一行代码就足够了,一切将由ContextCompat.getDrawable处理

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)

0

对于即使在应用了该线程的建议后,仍然有此问题要解决的人(我曾经是这样的人),请将此行添加到Application类的onCreate()方法上

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

如此此处所建议,有时需要使用它来访问资源中的向量,尤其是在处理菜单项等时


0

在Kotlin中,您可以使用扩展程序

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

    return  ContextCompat.getDrawable(this, id)
}

然后使用像

context.getMyDrawable(R.drawable.my_icon)

-2

Build.VERSION_CODES.LOLLIPOP现在应更改为BuildVersionCodes.Lollipop,即:

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

这不是BuildVersionCodesXamarin特有的课程吗?
Ted Hopp
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.