ChatGPT解决这个技术问题 Extra ChatGPT

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

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

发生了什么变化?

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

A
Alex Lockwood

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

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

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

您将根据 Activity 主题的指示获得一个样式化的 Drawable。这可能是您需要的。

B)没有主题属性的drawable

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) 也可以帮助你...
A
Alex Lockwood

编辑:查看我关于该主题的博客文章以获得更完整的解释

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

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 之前的版本中。库中有一个错误。
N
Nagaraju Gajula

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

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

编辑

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

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

有关详细信息,请点击此链接:ContextCompat


link 中并没有说 ResourcesCompat 已被弃用。它应该可以正常工作。
如果我想在单击存储在drawable中的列表项时将图像输入到列表视图中,在“你的drawable”中写什么
J
Jorgesys

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 才被弃用。:)”
D
Deepak Ror

在 Kotlin 中,您可以使用扩展

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

    return  ContextCompat.getDrawable(this, id)
}

然后像

context.getMyDrawable(R.drawable.my_icon)

A
Aalishan Ansari

尝试这个

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

R
Rahul Kushwaha

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

在科特林:-

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返回?在科特林。
D
Dasser Basyouni

您可以使用

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

这对我有用


在 pre lollipop 上使用应用程序上下文加载矢量可绘制崩溃。有什么解决办法吗?
@muthuraj 我不记得我用棒棒糖盒测试代码了,但是您可以尝试 getActivity() 或 getResources() 代替,这是否适合您的代码?
我正在使用 MVVM 模式,我需要在没有活动上下文的 ViewModel 中膨胀可绘制对象。它只有应用程序上下文。这就是我的问题。
J
Jay

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

D
Donald Duck

尝试这个:

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

虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
A
Adeel Ahmad

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

context.getDrawable(R.drawable.your_drawable_name)

See docs


C
ColdFire

zh API 级别 14

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

您应该围绕您的答案提供更多背景信息。
F
Farid Haq

现在你需要像这样实现

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

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

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

S
Stamatis Stiliats

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

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

正如 herehere 所建议的那样,有时这是从资源中访问向量所必需的,尤其是在您处理菜单项等时


K
Khalid Lakhani

如果您需要从其他面向 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);

C
ColdFire

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 的类吗?