首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ResourcesCompat.getDrawable()与AppCompatResources.getDrawable()

ResourcesCompat.getDrawable()与AppCompatResources.getDrawable()
EN

Stack Overflow用户
提问于 2017-03-24 16:42:56
回答 4查看 37.6K关注 0票数 68

我对这两个API有点困惑。

ResourcesCompat.getDrawable(参考资料,int id,Resources.Theme主题)

返回与特定资源ID关联并为指定主题设置样式的可绘制对象。将根据底层资源返回各种类型的对象--例如,纯色、PNG图像、可伸缩图像等。 在applied 21之前,主题将不应用,此方法只需调用getDrawable(int)即可。

AppCompatResources.getDrawable(上下文,int resId)

返回与特定资源ID关联的可绘制对象。 这种方法支持在没有平台支持的设备上向量和资源的膨胀。

问题

  1. 这两类(除向量通货膨胀外)有什么显著差异?
  2. 我应该选择哪一个而不是另一个?为什么?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-24 17:09:06

从这两种方法的源代码来看,它们似乎非常相似。如果你没有矢量,你很可能可以使用其中一个或另一个。

ResourcesCompat.getDrawable()将在API 21或更高版本上调用Resources#getDrawable(int, theme)。它还支持Android 4+。仅此而已:

代码语言:javascript
复制
public Drawable getDrawable(Resources res, int id, Theme theme)
        throws NotFoundException {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 21) {
        return ResourcesCompatApi21.getDrawable(res, id, theme);
    } else {
        return res.getDrawable(id);
    }
}

Where-in ResourcesCompatApi21只调用res.getDrawable(id, theme)。这意味着,如果设备不支持矢量绘图,则不允许绘制矢量绘图。然而,它将允许你通过一个主题。

同时,AppCompatResources.getDrawable(Context context, int resId)的代码更改最终会达到以下目的:

代码语言:javascript
复制
Drawable getDrawable(@NonNull Context context, @DrawableRes int resId, boolean failIfNotKnown) {
    checkVectorDrawableSetup(context);

    Drawable drawable = loadDrawableFromDelegates(context, resId);
    if (drawable == null) {
        drawable = createDrawableIfNeeded(context, resId);
    }
    if (drawable == null) {
        drawable = ContextCompat.getDrawable(context, resId);
    }

    if (drawable != null) {
        // Tint it if needed
        drawable = tintDrawable(context, resId, failIfNotKnown, drawable);
    }
    if (drawable != null) {
        // See if we need to 'fix' the drawable
        DrawableUtils.fixDrawable(drawable);
    }

    return drawable;
}

因此,如果可以,此实例将尝试绘制资源,否则它将在ContextCompat版本中查找以获取资源。如果必要的话,它甚至会使它变浅。但是,该方法只支持API 7+。

所以我想决定你是否应该使用任何一种,

  1. 您必须支持API 4、5或6吗?
代码语言:javascript
复制
- Yes: No choice but to use `ResourcesCompat` or `ContextCompat`.
- No: Keep going to #2.

  1. 你绝对需要提供一个定制的主题吗?
代码语言:javascript
复制
- Yes: No choice but to use `ResourcesCompat`
- No: Use `AppCompatResources`

票数 43
EN

Stack Overflow用户

发布于 2018-01-13 04:59:09

下面是我在一些测试之后的理解:

代码语言:javascript
复制
ContextCompat.getDrawable(@NonNull Context context, @DrawableRes int resId)

ResourcesCompat.getDrawable(@NonNull Resources res, @DrawableRes int id, @Nullable Theme theme)

AppCompatResources.getDrawable(@NonNull Context context, @DrawableRes int resId)

VectorDrawableCompat.create(@NonNull Resources res, @DrawableRes int resId, @Nullable Theme theme

我看到的第一件事是VectorDrawableCompatResourcesCompat可以指定一个主题。

( I)不使用

应用程序类的AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);onCreated中的应用

1)用于矢量图像

  • API >= 21
  • ContextCompat工作得很好
  • ResourcesCompat工作得很好
  • AppCompatResources工作得很好
  • VectorDrawableCompat工作得很好
  • API < 21
  • ContextCompat crash
  • ResourcesCompat crash
  • AppCompatResources工作得很好
  • VectorDrawableCompat工作得很好

2)用于正常图像

  • 在所有API级别中
  • ContextCompat工作得很好
  • ResourcesCompat工作得很好
  • AppCompatResources工作得很好
  • VectorDrawableCompat crash

(二)使用

应用程序类的AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);onCreated中的应用

1)用于矢量图像

  • 在所有API级别中
  • ContextCompat工作得很好
  • ResourcesCompat工作得很好
  • AppCompatResources工作得很好
  • VectorDrawableCompat工作得很好

2)用于正常图像的

  • 在所有API级别中
  • ContextCompat工作得很好
  • ResourcesCompat工作得很好
  • AppCompatResources工作得很好
  • VectorDrawableCompat crash
票数 98
EN

Stack Overflow用户

发布于 2017-03-24 18:35:24

ContextCompat

ResourcesCompatContextCompat和几乎所有的支持类--以Compat结尾的V4--可以避免在任何地方编写if (Build.VERSION.SDK_INT >= X)检查。就这样。例如,而不是

代码语言:javascript
复制
final Drawable d;
if (Build.VERSION.SDK_INT < 21) {
    // Old method, drawables cannot contain theme references.
    d = context.getResources().getDrawable(R.drawable.some_image);
} else {
    // Drawables on API 21 can contain theme attribute references.
    // Context#getDrawable only exists since API 21.
    d = context.getDrawable(R.drawable.some_image);
}

你可以写

代码语言:javascript
复制
final Drawable d = ContextCompat.getDrawable(context, R.drawable.some_image);

例如,注释中描述的限制适用于

代码语言:javascript
复制
// This line is effectively equivalent to the above.
ResourcesCompat.getDrawable(context.getResources(), R.drawable.some_image, context.getTheme());

实际上并没有在Lollipop之前应用主题属性(这在文档中是这么说的)。但是,您不必编写“如果检查”,代码也不会在旧设备上崩溃,因为您实际上并没有使用新的API。

AppCompatResources

另一方面,AppCompatResources实际上将帮助您为旧平台(支持向量、颜色状态列表中的主题引用)带来新功能。

我应该选择哪一个而不是另一个?为什么?

使用AppCompatResources与appcompat-v7库的其余部分获得一致的结果。你会得到:

  • getColorStateList可以解析带有主题属性引用的颜色(如android:alpha="?android:disabledAlpha"),
  • getDrawable支持所有平台上的膨胀向量,这些矢量绘图还可以理解主题属性引用(例如android:tint="?colorControlNormal"),
  • appcompat-v7绘图和颜色,如检查点或单选按钮,将有适当的颜色定义提供的上下文主题,
  • 如果上面的内容不适用,那么它将返回到ContextCompat
票数 27
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43004886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档