DrawableCompat setTint not working on API 19

2020-02-21 06:14发布

问题:

I am using the DrawableCompat for tinting drawable as below, tinting doesn't seem to be working on API 19. I am using the support lib version 23.3.0

Drawable drawable = textView.getCompoundDrawables()[drawablePosition];
if (drawable != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            drawable.setTint(color);
        } else {
            DrawableCompat.setTint(DrawableCompat.wrap(drawable), color);
        }
    }

回答1:

I had the same problem. I combined the posts in https://stackoverflow.com/a/30928051 and tried the APIs 17, 19, 21, 22, 23 and N Preview 3 with SupportLib 23.4.0 to find a solution.

Even if it is mentioned, that the compat-class will use a filter for pre-lollipop-devices (see https://stackoverflow.com/a/27812472/2170109), it's not working.

Now, I check the API myself and use the following code, which is working on all tested APIs (for 17 and up).

    // https://stackoverflow.com/a/30928051/2170109
    Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
    image.setImageDrawable(drawable);

    /*
     * need to use the filter | https://stackoverflow.com/a/30880522/2170109
     * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
     */
    int color = ContextCompat.getColor(context, R.color.yourcolor);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        DrawableCompat.setTint(drawable, color);

    } else {
        drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }


回答2:

Works on API 15-25 using AppCompat Support Library (tested on 24.1.1 and above).

public static Drawable getTintedDrawable(@NonNull final Context context,
                                         @DrawableRes int drawableRes, @ColorRes int colorRes) {
    Drawable d = ContextCompat.getDrawable(context, drawableRes);
    d = DrawableCompat.wrap(d);
    DrawableCompat.setTint(d.mutate(), ContextCompat.getColor(context, colorRes));
    return d;
}


回答3:

I think that after wrapping your drawable, you would need to call mutate() on it. See this: https://stackoverflow.com/a/30928051/3032209



回答4:

I made following helper method to set a drawable with tint and it works at least from API level 16 up to x. The color is a themed color and therefore resolved via attribute.

  public static Drawable getTintedDrawable(int drawableResourceId, int colorAttribute) {
    YourApplication = YourApplication.getInstance();
    Drawable drawable = ContextCompat.getDrawable(application, drawableResourceId);
    drawable = DrawableCompat.wrap(drawable);
    int tintColor = ContextCompat.getColor(application, application.getThemedResourceId(colorAttribute));
    DrawableCompat.setTint(drawable, tintColor);
    return drawable;
  }

Without the drawable.wrap it works on higher versions but not on api level 16.



回答5:

based on @localhost answer

Drawable d = DrawableCompat.wrap(ContextCompat.getDrawable(this, R.drawable.ic_rate));
DrawableCompat.setTint(d, Color.parseColor("#AAAAAA"));
l.setLogo(d);

I tried on API 19>25 and it works well



回答6:

val textInput = EditText(context)

val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
        drawable?.let { myDrawable ->
            DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
            textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
        }



回答7:

No answer works for me on Honor 4X. so I searched more and found this:

Just you need to ask your drawable to update itself by .invalidateSelf()

private void setTint(Drawable drawable, int color) {
    DrawableCompat.setTint(drawable, color);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        drawable.invalidateSelf();
}

Resourse: Tips for DrawableCompat.setTint() Under API 21