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

Posted

技术标签:

【中文标题】Android getResources().getDrawable() 已弃用 API 22【英文标题】:Android getResources().getDrawable() deprecated API 22 【发布时间】:2015-05-16 10:54:06 【问题描述】:

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

发生了什么变化?

【问题讨论】:

您能具体说明您的问题吗?不推荐使用Resources 类的方法getDrawable (int id) 是对的。您现在应该使用方法 getDrawable (int id, Resources.Theme theme) 和新的主题参数。 ContextCompat.getDrawable(context, R.color.color_name) 您可以查看有关此主题的 my blog post,以更全面地了解为什么不推荐使用 Resources#getDrawable(int)Resources#getColor(int) Google 应该为每个已弃用的功能提供快速修复。我在这里发了一个帖子:code.google.com/p/android/issues/detail?id=219495 【参考方案1】:

您可以选择以正确的方式(以及未来证明)处理这种弃用,具体取决于您正在加载的绘图类型:


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); 我这样声明: public static void setImageButtonEnabled(Context ctxt, boolean enabled, ImageButton item, int iconResId) item.setEnabled(enabled);可绘制的 originalIcon = ResourcesCompat.getDrawable(ctxt.getResources(), iconResId, null);可绘制图标 = 启用? originalIcon : convertDrawableToGrayScale(originalIcon); item.setImageDrawable(icon);并这样称呼它: Utility.setImageButtonEnabled(getContext(), false, back, R.drawable.arrow_left); 更准确地说,崩溃似乎正在发生,因为我的图标是可绘制的矢量。 xamarin 版本:ResourcesCompat.GetDrawable(Resources, Resource.Drawable.name, null); 我再补充一句,ContextCompat.getColor(context,color) 也可以帮到你...【参考方案2】:

编辑:请参阅my blog post 以获得更完整的说明


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

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)

【讨论】:

我认为OP也引用了Context类的getDrawable (int id)方法。这与getResources().getDrawable(id, getTheme()); 相同,也使用新的API。 根据文档,使用getDrawable(int, Resources.Theme)需要最低API级别21。 @Prince 该方法已添加到 API 21,但直到 API 22 才被弃用。:) Android 文档还建议使用Context::getDrawable(int) method,但由于它仅在 API 21 中引入,因此 ContextCompat 似乎是最佳选择。 此答案不适用于 .svg 文件,在 API 21 之前的版本中。库中存在错误。【参考方案3】:

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

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

编辑

ResourcesCompat 现在也已弃用。但是你可以使用这个:

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

更多详情请点击此链接:ContextCompat

【讨论】:

现在也被贬低了:plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM 请查看此链接:developer.android.com/reference/android/support/v4/content/…, int) link 中并没有说 ResourcesCompat 已被弃用。它应该可以正常工作。 如果我想在单击存储在drawable中的列表项时将图像输入到列表视图中,在“你的drawable”中写什么【参考方案4】:

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

getDrawable (int id, Resources.Theme 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 才被弃用。:)”【参考方案5】:

在 Kotlin 中你可以使用扩展

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

    return  ContextCompat.getDrawable(this, id)

然后使用like

context.getMyDrawable(R.drawable.my_icon)

【讨论】:

【参考方案6】:

试试这个

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

【讨论】:

【参考方案7】:

getDrawable(int drawable) 在 API 级别 22 中已弃用。 如需参考,请参阅此 link

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

getDrawable(int id, Resources.Theme theme)

对于解决方案这样做:-

在 Java 中:-

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

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

在 Kotlin 中:-

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

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

希望对您有所帮助。谢谢。

【讨论】:

值得一提的是,getDrawable(DrawableRes int id, Theme theme)在找不到资源时会抛出异常,而getDrawable(Context context, int id)是可空的,所以必须与 Drawable 一起返回?在 Kotlin 中。【参考方案8】:

你可以使用

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

这对我有用

【讨论】:

使用应用程序上下文加载矢量可绘制在棒棒糖前崩溃。有什么解决办法吗? @muthuraj 我不记得我对棒棒糖案例的代码进行了测试,但是您可以尝试 getActivity() 或 getResources() 代替,这是否适合您的代码? 我正在使用 MVVM 模式,我需要在没有活动上下文的 ViewModel 中填充可绘制对象。它只有应用程序上下文。这就是我的问题。【参考方案9】:

只是我如何在数组中解决问题以加载 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)));

【讨论】:

【参考方案10】:

试试这个:

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

【讨论】:

虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。【参考方案11】:

如果您的目标是 SDK > 21(棒棒糖或 5.0),请使用

context.getDrawable(R.drawable.your_drawable_name)

See docs

【讨论】:

【参考方案12】:

zh api 级别 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));

【讨论】:

你应该提供更多关于你的答案的上下文。【参考方案13】:

现在你需要像这样实现

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

单行代码就够了,一切由 ContextCompat.getDrawable 处理

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

【讨论】:

【参考方案14】:

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

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

正如 here 和 here 建议的那样,有时需要从资源中访问向量,尤其是在处理菜单项等时

【讨论】:

【参考方案15】:

如果您需要从其他面向 SDK 23 及更高版本的应用程序绘制

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

【讨论】:

【参考方案16】:

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

【讨论】:

BuildVersionCodes 不是 Xamarin 特有的类吗?

以上是关于Android getResources().getDrawable() 已弃用 API 22的主要内容,如果未能解决你的问题,请参考以下文章

Android getResources的作用和需要注意点

android的getResources()报错如何解决?

赵雅智_Android的getResources()资源引用

Android 获取 上下文环境参数 getResources

Android之获取string.xml文件里面的方法

Android中getResources().getConfiguration()方法的作用