【问题标题】:Android getResources().getDrawable() deprecated API 22Android getResources().getDrawable() 已弃用 API 22
【发布时间】:2023-03-17 07:24:01
【问题描述】:

现在不推荐使用新的 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

标签: android android-drawable android-resources android-5.1.1-lollipop


【解决方案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

【讨论】:

【解决方案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)

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

            【讨论】:

              【解决方案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 特有的类吗?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-09-17
                • 1970-01-01
                • 2019-07-30
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多