TextView tint on AppCompat

For API 23 and up, just set it in your layout: android:drawableTint="@color/custom_color"

If you need backward compatibility, you will need to set it programmatically. In Kotlin, you can create an extension function like:

fun TextView.setDrawableColor(@ColorRes color: Int) {
    compoundDrawables.filterNotNull().forEach {
        it.colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
    }
}

And use it like: textView.setDrawableColor(R.color.custom_color)

Please note that filterNotNull() is very important here since the list of drawables will likely have some null values (for all the TextView drawables that have not been set).


Here is a backward compatible TextView.

Usage:

<com.github.mrezanasirloo.TextViewCompatTint
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableStart="@drawable/ic_comment_black_14dp"
    app:drawableTint="@color/colorPrimary"
    tools:text="28"
    />

gist


For Api level 23 >= android:drawableTint="@color/colorPrimary"

For Api level < Api level 23 :

JAVA

private void setTextViewDrawableColor(@RecentlyNonNull TextView textView,@ColorRes int color) {
        for (Drawable drawable : textView.getCompoundDrawables()) {
            if (drawable != null) {
                drawable.setColorFilter(new PorterDuffColorFilter(getColor(color), PorterDuff.Mode.SRC_IN));
            }
        }
    }

USE: setTextViewDrawableColor(txtMyDemoText,R.color.colorPrimary)


Kotlin Extension Function

  fun TextView.setDrawableColor(@ColorRes color: Int) {
          compoundDrawables.filterNotNull().forEach {
              it.colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
        }
   }

USE : txtMyDemoText.setDrawableColor(R.color.colorPrimary)


Looking at the source for AppCompatCheckedTextView I've finally figured it out. It only tints the checkMark. Since it derives from CheckedTextView, which derives from TextView, drawableRight only gets tinted on lollipop. Looking at the source for AppCompatTextView, it only provides a backwards compatible textAllCaps. So AFAIK, there is no built-in way to tint drawableRight and the like pre-lollipop. If you want a more customizable solution, you might need to put your drawables in a layout.

The updated style:

<style name="CheckBoxStyle" parent="android:Widget.TextView">
    <item name="android:textAppearance">@style/TextAppearance.AppCompat</item>
    <item name="android:checkMark">?android:attr/listChoiceIndicatorSingle</item>
    <item name="android:clickable">true</item>
    <item name="android:background">?attr/selectableItemBackground</item>
    <item name="android:gravity">center_vertical</item>
    <item name="android:paddingTop">8dp</item>
    <item name="android:paddingBottom">8dp</item>
</style>