Search code examples
javaandroidandroid-vectordrawable

How to set ImageView's tint under (Expandable)ListAdapter?


Preamble

I've been g00gling for half an hour now, and it seems like I'm really missing something important.

Note: I've already tried the solutions for these questions

How to change color of vector drawable path on button click
How to set tint for an image view programmatically in android?
Changing ImageView source

These solutions either recolor ALL ImageView srcs or they don't do anything at all (vector remains black).

My drawable is a vector asset from the material icons directory:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">

    <path
        android:fillColor="#FF000000"
        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z" />
</vector>

My ImageView:

<ImageView
        android:id="@+id/gradeBullet"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="25.5dp"
        android:layout_marginTop="25.5dp"
        app:srcCompat="@drawable/importantgrade" />

I would like to do this with *Compat, because I'd also like to support earlier APIs (API>17).

My ImageView: ImageView gradeBullet = convertView.findViewById(R.id.gradeBullet);

Try I.

MyAmazingAdapter.java - getChildView(...)

gradeBullet.setColorFilter(ContextCompat.getColor(context, gradeObj.colorId), PorterDuff.Mode.MULTIPLY);

Result: Does nothing.

Try II.

MyAmazingAdapter.java - getChildView(...)

DrawableCompat.setTint(gradeBullet.getDrawable(), ContextCompat.getColor(context, R.color.myColor));

Result: Recolors everything.

Try III.

MyAmazingAdapter.java - getChildView(...)

VectorDrawableCompat drawable = (VectorDrawableCompat) gradeBullet.getDrawable();
drawable.setTint(ContextCompat.getColor(context, gradeObj.colorId));
gradeBullet.setImageDrawable(drawable);

Result: Gives a weird color. (Definitely not what I want, it's closer to the original color)

Try IV.

All the above with a final to the gradeBullet, got the same results.

Some other info

  • The gradeObj.colorId is different for every childView.
  • Using shapes and setColor instead of SVG is not what I want.
  • Currently only tested with API lvl 26
  • MyAmazingAdapter.java extends BaseExpandableListAdapter

If you'd like more info, just mention it in a comment.


Solution

  • You can try your first method with PorterDuff.Mode.SRC_IN or PorterDuff.Mode.SRC_ATOP instead of PorterDuff.Mode.MULTIPLY.

    PorterDuff.mode

    Hope this helps.