C贸mo corregir el error Drawable.setTint en API 21 SDK de Android

Hola, en esta publicaci贸n, nuestro desarrollador de Android Vlad Titov hablar谩 sobre c贸mo resolver el problema usando la herramienta de cambio de color para Drawable. Vamos.

En la versi贸n 21 de la API del SDK de Android, hay una herramienta universal para cambiar el color de todos los Drawable: Drawable.setTint (int color) . Pero solo en esta misma versi贸n, no funciona para algunos herederos de Drawable, a saber, GradientDrawable, InsetDrawable, RippleDrawable y todos los herederos de DrawableContainer. 

Si miramos las fuentes API 21, digamos, GradientDrawable (descendiente directo de Drawable), no encontraremos el m茅todo setTint anulado y sus variaciones. Esto significa que en esta implementaci贸n, los desarrolladores simplemente no admitieron esta funci贸n.

. androidx.core:core. tinting 14-22, WrappedDrawableApi14 WrappedDrawableApi21. , , . 

Drawable, DrawableCompat.wrap(Drawable). , ColorStateList , Drawable Drawable.

final ColorStateList tintList = mState.mTint;
final PorterDuff.Mode tintMode = mState.mTintMode;

if (tintList != null && tintMode != null) {
   final int color = tintList.getColorForState(state, tintList.getDefaultColor());
   if (!mColorFilterSet || color != mCurrentColor || tintMode != mCurrentMode) {
       setColorFilter(color, tintMode);
       mCurrentColor = color;
       mCurrentMode = tintMode;
       mColorFilterSet = true;
       return true;
   }
} else {
   mColorFilterSet = false;
   clearColorFilter();
}

Drawable.setState(int[] stateSet).

Drawable. , , GradientDrawable , , setShape, setGradientType ... , Drawable (DrawableCompat.unwrap(Drawable)). . , , Drawable. stateful, , , .

, . 

Si su tinte consta de un solo color, puede hacer lo siguiente en cualquier momento:

val wrapped = DrawableCompat.wrap(drawable)
wrapped.setTint(...)
drawable = DrawableCompat.unwrap(wrapped)

Despu茅s de eso, haga su negocio con valent铆a.

De lo contrario, tiene sentido utilizar la siguiente soluci贸n:

class GradientDrawableWrapper(
    val original: GradientDrawable, 
    var tint: ColorStateList
) {

    fun get(): Drawable {
        return wrap()
    }

    fun setShape(@Shape shape: Int) {
        original.setShape(shape)
    }

    // other specific method proxies...

    private fun wrap(): Drawable {
        val wrapped = DrawableCompat.wrap(original)
        wrapped.setTint(tint)
        return wrapped
    }
}

Esta soluci贸n parece un poco voluminosa, pero resuelve por completo el problema indicado.




All Articles