Je suis un peu confus avec ces deux API.
ResourcesCompat.getDrawable (Ressources res, int id, Resources.Theme theme)
Renvoie un objet dessinable associé à un ID de ressource particulier et stylisé pour le thème spécifié. Différents types d'objets seront retournés en fonction de la ressource sous-jacente - par exemple, une couleur unie, une image PNG, une image évolutive, etc.
Avant le niveau 21 de l'API, le thème ne sera pas appliqué et cette méthode appelle simplement via getDrawable (int).
AppCompatResources.getDrawable (Contexte contextuel, int resId)
Renvoie un objet dessinable associé à un ID de ressource particulier.
Cette méthode prend en charge l'inflation des ressources vectorielles et vectorielles animées sur les appareils où le support de la plateforme n'est pas disponible.
En regardant le code source des deux méthodes, elles semblent très similaires. Si vous n'avez pas de vecteurs, vous pourriez probablement vous en sortir en utilisant l'un ou l'autre.
ResourcesCompat.getDrawable()
appellera Resources#getDrawable(int, theme)
sur les API 21 ou plus. Il prend également en charge Android API 4+. Ce n'est pas plus que cela:
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);
}
}
Où-in ResourcesCompatApi21
Appelle simplement res.getDrawable(id, theme)
. Cela signifie qu'il ne permettra pas de dessiner des dessinables vectoriels si le périphérique ne prend pas en charge les dessinables vectoriels. Il vous permettra cependant de passer dans un thème.
Pendant ce temps, le changement de code pour AppCompatResources.getDrawable(Context context, int resId)
finit par arriver à ceci:
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;
}
Ainsi, cette instance tentera de dessiner la ressource si elle le peut, sinon elle regarde dans la version ContextCompat
pour obtenir la ressource. Ensuite, il le teint même si nécessaire. Cependant, cette méthode ne prend en charge que l'API 7+.
Donc, je suppose que pour décider si vous devez utiliser l'un ou l'autre,
Devez-vous prendre en charge les API 4, 5 ou 6?
ResourcesCompat
ou ContextCompat
.Avez-vous absolument besoin de fournir un thème personnalisé?
ResourcesCompat
AppCompatResources
Voici ma compréhension après un test
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
La première chose à voir est VectorDrawableCompat
et ResourcesCompat
peut un thème spécifique
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
dans onCreated
de la classe Application
1) Pour l'image vectorielle
API> = 21
ContextCompat
fonctionne bienResourcesCompat
fonctionne bienAppCompatResources
fonctionne bienVectorDrawableCompat
fonctionne bienAPI <21
ContextCompat
crashResourcesCompat
crashAppCompatResources
fonctionne bienVectorDrawableCompat
fonctionne bien2) Pour une image normale
ContextCompat
fonctionne bienResourcesCompat
fonctionne bienAppCompatResources
fonctionne bienVectorDrawableCompat
crashAppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
dans onCreated
de la classe Application
1) Pour l'image vectorielle
ContextCompat
fonctionne bienResourcesCompat
fonctionne bienAppCompatResources
fonctionne bienVectorDrawableCompat
fonctionne bien2) Pour une image normale
ContextCompat
fonctionne bienResourcesCompat
fonctionne bienAppCompatResources
fonctionne bienVectorDrawableCompat
crashResourcesCompat
, ContextCompat
et à peu près n'importe quelle classe de support-v4 se terminant par Compat
vous évite d'écrire des vérifications if (Build.VERSION.SDK_INT >= X)
partout. C'est ça. Par exemple au lieu de
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);
}
tu peux écrire
final Drawable d = ContextCompat.getDrawable(context, R.drawable.some_image);
Les limites décrites dans les commentaires s'appliquent, par exemple
// This line is effectively equivalent to the above.
ResourcesCompat.getDrawable(context.getResources(), R.drawable.some_image, context.getTheme());
n'applique pas réellement les attributs de thème avant Lollipop (cela est dit dans la documentation). Mais vous n'avez pas à écrire si les vérifications et votre code ne plantent pas sur les anciens appareils parce que vous n'utilisez pas réellement de nouvelles API là-bas.
AppCompatResources
d'autre part, vous aidera en fait à apporter de nouvelles fonctionnalités aux anciennes plates-formes (vecteurs de support, références de thème dans les listes d'état des couleurs).
Laquelle devrais-je préférer à une autre et pourquoi?
Utilisez AppCompatResources
pour obtenir des résultats cohérents avec le reste de la bibliothèque appcompat-v7. Tu auras:
getColorStateList
qui peut résoudre les couleurs avec des références d'attribut de thème (comme Android:alpha="?android:disabledAlpha"
),getDrawable
qui prend en charge le gonflement des vecteurs sur toutes les plates-formes et ces drawables vectoriels comprennent également les références d'attribut de thème (par exemple Android:tint="?colorControlNormal"
),ContextCompat
.