theme textappearance temas style studio para apptheme java android android-resources android-theme android-styles

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:

  • getColorStateList que puede resolver colores con referencias de atributos del tema (como android:alpha="?android:disabledAlpha" ),
  • getDrawable que 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 ContextCompat todos 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

  1. ¿Cuál es la diferencia significativa entre estas dos clases (además de la inflación vectorial )?
  2. ¿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

    • ContextCompat funciona bien
    • ResourcesCompat funciona bien
    • AppCompatResources funciona bien
    • VectorDrawableCompat funciona bien
  • API <21

    • ContextCompat crash
    • Choque de ResourcesCompat
    • AppCompatResources funciona bien
    • VectorDrawableCompat funciona bien

2) Para imagen normal.

  • En todo nivel
    • ContextCompat funciona bien
    • ResourcesCompat funciona bien
    • AppCompatResources funciona bien
    • VectorDrawableCompat crash

II) Utilizando

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); en onCreated de clase de aplicación

1) Para imagen vectorial

  • En todo nivel
    • ContextCompat funciona bien
    • ResourcesCompat funciona bien
    • AppCompatResources funciona bien
    • VectorDrawableCompat funciona bien

2) Para imagen normal.

  • En todo nivel
    • ContextCompat funciona bien
    • ResourcesCompat funciona bien
    • AppCompatResources funciona bien
    • VectorDrawableCompat crash

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,

  1. ¿Tienes que soportar API 4, 5 o 6?

    • Sí: no hay más remedio que usar ResourcesCompat o ContextCompat .
    • No: sigue yendo al # 2.
  2. ¿Es absolutamente necesario proporcionar un tema personalizado?

    • Sí: no hay más remedio que utilizar ResourcesCompat
    • No: utilizar AppCompatResources