API 21 AndroidSDKのDrawable.setTintバグを修正する方法

こんにちは、この投稿では、Android開発者のVlad Titovが、Drawableの色変更ツールを使用して問題を解決する方法について説明します。行く。

Android SDK APIの21番目のバージョンでは、すべてのDrawableの色を変更するためのユニバーサルツールであるDrawable.setTint(int color)が導入されていますただし、このバージョンでは、Drawableの一部の継承者、つまりGradientDrawable、InsetDrawable、RippleDrawable、およびDrawableContainerのすべての継承者では機能しません。 

たとえば、GradientDrawable(Drawableの直接の子孫)などのAPI 21ソースを見ると、オーバーライドされた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, , , .

, . 

色合いが1色のみで構成されている場合は、いつでも次の操作を実行できます。

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