我对这两个API有点困惑。
ResourcesCompat.getDrawable(参考资料,int id,Resources.Theme主题)
返回与特定资源ID关联并为指定主题设置样式的可绘制对象。将根据底层资源返回各种类型的对象--例如,纯色、PNG图像、可伸缩图像等。 在applied 21之前,主题将不应用,此方法只需调用getDrawable(int)即可。
AppCompatResources.getDrawable(上下文,int resId)
返回与特定资源ID关联的可绘制对象。 这种方法支持在没有平台支持的设备上向量和资源的膨胀。
问题
发布于 2017-03-24 17:09:06
从这两种方法的源代码来看,它们似乎非常相似。如果你没有矢量,你很可能可以使用其中一个或另一个。
ResourcesCompat.getDrawable()
将在API 21或更高版本上调用Resources#getDrawable(int, theme)
。它还支持Android 4+。仅此而已:
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)
的代码更改最终会达到以下目的:
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+。
所以我想决定你是否应该使用任何一种,
- Yes: No choice but to use `ResourcesCompat` or `ContextCompat`.
- No: Keep going to #2.
- Yes: No choice but to use `ResourcesCompat`
- No: Use `AppCompatResources`
发布于 2018-01-13 04:59:09
下面是我在一些测试之后的理解:
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
我看到的第一件事是VectorDrawableCompat
和ResourcesCompat
可以指定一个主题。
( I)不使用
应用程序类的AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
在onCreated
中的应用
1)用于矢量图像
ContextCompat
工作得很好ResourcesCompat
工作得很好AppCompatResources
工作得很好VectorDrawableCompat
工作得很好ContextCompat
crashResourcesCompat
crashAppCompatResources
工作得很好VectorDrawableCompat
工作得很好2)用于正常图像
ContextCompat
工作得很好ResourcesCompat
工作得很好AppCompatResources
工作得很好VectorDrawableCompat
crash(二)使用
应用程序类的AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
在onCreated
中的应用
1)用于矢量图像
ContextCompat
工作得很好ResourcesCompat
工作得很好AppCompatResources
工作得很好VectorDrawableCompat
工作得很好2)用于正常图像的
ContextCompat
工作得很好ResourcesCompat
工作得很好AppCompatResources
工作得很好VectorDrawableCompat
crash发布于 2017-03-24 18:35:24
ContextCompat
ResourcesCompat
、ContextCompat
和几乎所有的支持类--以Compat
结尾的V4--可以避免在任何地方编写if (Build.VERSION.SDK_INT >= X)
检查。就这样。例如,而不是
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);
}
你可以写
final Drawable d = ContextCompat.getDrawable(context, R.drawable.some_image);
例如,注释中描述的限制适用于
// 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"
),ContextCompat
。https://stackoverflow.com/questions/43004886
复制相似问题