كيفية إصلاح خطأ Drawable.setTint في API 21 Android SDK

مرحبًا ، في هذا المنشور ، سيتحدث مطور android لدينا فلاد تيتوف عن كيفية حل المشكلة باستخدام أداة تغيير اللون لـ Drawable. اذهب.

في الإصدار الحادي والعشرين من Android SDK API ، هناك أداة عالمية لتغيير اللون لجميع Drawable - Drawable.setTint (لون int) . ولكن فقط في هذا الإصدار بالذات ، لا يعمل مع بعض ورثة 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