如何修复API 21 Android SDK中的Drawable.setTint错误

嗨,在本文中,我们的Android开发人员Vlad Titov将讨论如何使用Drawable的颜色更改工具解决问题。走。

在Android SDK API的第21版中,有一个通用工具可以更改所有Drawable- Drawable.setTint(int color)的颜色但是仅在此版本中,它不适用于Drawable的某些继承者,即GradientDrawable,InsetDrawable,RippleDrawable和DrawableContainer的所有继承者。 

如果查看API 21的源代码,例如GradientDrawable(Drawable的直接后代),我们将找不到覆盖的setTint方法及其变体。这意味着在此实现中,开发人员根本不支持此功能。

. 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, , , .

, . 

如果您的色彩仅由一种颜色组成,则可以随时执行以下操作:

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

之后,大胆地开展业务。

否则,可以使用以下解决方案:

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
    }
}

该解决方案看起来有些庞大,但是可以完全解决所指出的问题。




All Articles