java - textappearance - theme editor android studio
ResourcesCompat.getDrawable() vs AppCompatResources.getDrawable() (3)
ContextCompat
ResourcesCompat , ContextCompat y prácticamente cualquier clase de support-v4 que termina con Compat te ahorra escribir if (Build.VERSION.SDK_INT >= X) verifica en todas partes. Eso es. Por ejemplo, en lugar 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);
}
puedes escribir
final Drawable d = ContextCompat.getDrawable(context, R.drawable.some_image);
Se aplican los límites descritos en los comentarios, por ejemplo.
// This line is effectively equivalent to the above.
ResourcesCompat.getDrawable(context.getResources(), R.drawable.some_image, context.getTheme());
en realidad no aplica los atributos del tema antes de Lollipop (esto se dice en la documentación). Pero no tiene que escribir si el cheque y su código no se bloquean en dispositivos antiguos porque en realidad no está usando nuevas API allí.
AppCompatResources
AppCompatResources otra parte, AppCompatResources realmente te ayudará a llevar nuevas funciones a plataformas antiguas (vectores de soporte, referencias de temas en listas de estados de color).
¿Cuál debería preferir a otra y por qué?
Use AppCompatResources para obtener resultados consistentes con el resto de la biblioteca appcompat-v7. Obtendrás:
-
getColorStateListque puede resolver colores con referencias de atributos del tema (comoandroid:alpha="?android:disabledAlpha"), -
getDrawableque admite inflar vectores en todas las plataformas y estos vectores dibujables también comprenden las referencias de atributos del tema (por ejemplo,android:tint="?colorControlNormal"), - Los elementos dibujables y colores de appcompat-v7 como marcas de verificación o botones de radio tendrán colores adecuados definidos por el tema de contexto proporcionado,
- Si lo anterior no se aplica, vuelve a
ContextCompattodos modos.
Estoy un poco confundido con estas dos APIs.
ResourcesCompat.getDrawable (Resources res, int id, Resources.Theme theme)
Devuelve un objeto dibujable asociado con un ID de recurso particular y con un estilo para el tema especificado. Se devolverán varios tipos de objetos según el recurso subyacente, por ejemplo, un color sólido, una imagen PNG, una imagen escalable, etc.
Antes del nivel de API 21, el tema no se aplicará y este método simplemente llama a getDrawable (int).
AppCompatResources.getDrawable (contexto de contexto, int resId)
Devuelve un objeto dibujable asociado con un ID de recurso particular.
Este método admite la inflación de recursos vectoriales y vectores animados en dispositivos donde no está disponible el soporte de plataforma.
Pregunta
- ¿Cuál es la diferencia significativa entre estas dos clases (además de la inflación vectorial )?
- ¿Cuál debería preferir a otra y por qué?
Aquí está mi comprensión después de algunas pruebas
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
Lo primero que se ve es VectorDrawableCompat y ResourcesCompat puede tema específico
I) Sin usar
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); en onCreated de clase de aplicación
1) Para imagen vectorial
API> = 21
-
ContextCompatfunciona bien -
ResourcesCompatfunciona bien -
AppCompatResourcesfunciona bien -
VectorDrawableCompatfunciona bien
-
API <21
-
ContextCompatcrash - Choque de
ResourcesCompat -
AppCompatResourcesfunciona bien -
VectorDrawableCompatfunciona bien
-
2) Para imagen normal.
- En todo nivel
-
ContextCompatfunciona bien -
ResourcesCompatfunciona bien -
AppCompatResourcesfunciona bien -
VectorDrawableCompatcrash
-
II) Utilizando
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); en onCreated de clase de aplicación
1) Para imagen vectorial
- En todo nivel
-
ContextCompatfunciona bien -
ResourcesCompatfunciona bien -
AppCompatResourcesfunciona bien -
VectorDrawableCompatfunciona bien
-
2) Para imagen normal.
- En todo nivel
-
ContextCompatfunciona bien -
ResourcesCompatfunciona bien -
AppCompatResourcesfunciona bien -
VectorDrawableCompatcrash
-
Mirando el código fuente de los dos métodos, parecen muy similares. Si no tiene vectores, probablemente podría salirse con la suya usando uno u otro.
ResourceCompat.getDrawable() llamará a Resources#getDrawable(int, theme) en las API 21 o superiores. También es compatible con las API de Android 4+. No es más que esto:
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 simplemente llama res.getDrawable(id, theme) . Esto significa que no permitirá dibujar vectores dibujables si el dispositivo no es compatible con vectores dibujables. Sin embargo, le permitirá pasar en un tema.
Mientras tanto, el cambio de código para AppCompatResources.getDrawable(Context context, int resId) finalmente AppCompatResources.getDrawable(Context context, int resId) en esto:
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;
}
Entonces, esta instancia intentará dibujar el recurso si puede, de lo contrario, buscará en la versión ContextCompat para obtener el recurso. Entonces incluso se teñirá si es necesario. Sin embargo, este método solo es compatible con API 7+.
Así que supongo que para decidir si debes usar cualquiera,
¿Tienes que soportar API 4, 5 o 6?
- Sí: no hay más remedio que usar
ResourcesCompatoContextCompat. - No: sigue yendo al # 2.
- Sí: no hay más remedio que usar
¿Es absolutamente necesario proporcionar un tema personalizado?
- Sí: no hay más remedio que utilizar
ResourcesCompat - No: utilizar
AppCompatResources
- Sí: no hay más remedio que utilizar