Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android TextView DrawableTint on pre v23 devices

Is there any way we can tint the Drawable used in the TextView? DrawableTint works only on API level 23 and above.

Currently I'm using a Vertical Linear Layout to achieve my requirement.

<LinearLayout style="@style/ChoiceIllustratorIconTextContainerStyle">

  <ImageView
    style="@style/ChoiceIllustratorImageStyle"
    android:contentDescription="@string/cd_university"
    android:src="@drawable/ic_account_balance_white_24dp" />

  <TextView
    style="@style/ChoiceIllustratorTextStyle"
    android:text="@string/ci_text_university" />

</LinearLayout>

And it looks like,enter image description here

Android studio is suggesting me to use Compound Drawble with TextView to achieve this. And I'm able to achieve it, but I cannot find a way to Tint the drawable.

<TextView
   style="@style/ChoiceIllustratorTextStyle"
   android:drawablePadding="4dp"
   android:drawableTop="@drawable/ic_account_balance_white_24dp"
   android:text="@string/ci_text_university" />
like image 672
Nishanth Sreedhara Avatar asked Jan 11 '17 10:01

Nishanth Sreedhara


3 Answers

AndroidX appcompat library supports tinting in TextView since version 1.1.0-alpha03 [ref].

Add dependencies to appcompat library

dependencies {
  implementation "androidx.appcompat:appcompat:1.1.0"
}

Then drawable in TextView can be tinted from XML like this

<TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  app:drawableStartCompat="@drawable/ic_plus"
  app:drawableTint="@color/red" />

Don't forget to include

xmlns:app="http://schemas.android.com/apk/res-auto"

and to extend your Activity from AppCompatActivity.

like image 99
shinwan Avatar answered Nov 13 '22 16:11

shinwan


The programmatic way to do this is

       Drawable[] drawables = textView.getCompoundDrawables();
       if (drawables[0] != null) {  // left drawable
           drawables[0].setColorFilter(color, Mode.MULTIPLY);
       }

This works for all API levels.

This is your best option for pre-Marshmallow devices.

like image 24
kris larson Avatar answered Nov 13 '22 16:11

kris larson


This answer is based on @kris larson suggestion.

I use the following methods and it is working fine on all devices.

setTintedCompoundDrawable a custom method that takes the TextView to which you would want to set the compound drawable, a drawable res id & and the res id of your color choice.

private void setTintedCompoundDrawable(TextView textView, int drawableRes, int tintRes) {
    textView.setCompoundDrawablesWithIntrinsicBounds(
            null,  // Left
            Utils.tintDrawable(ContextCompat.getDrawable(getContext(), drawableRes),
                    ContextCompat.getColor(getContext(), tintRes)), // Top
            null, // Right
            null); //Bottom
    // if you need any space between the icon and text.
    textView.setCompoundDrawablePadding(12);
}

Tint tintDrawable method goes like this:

public static Drawable tintDrawable(Drawable drawable, int tint) {
    drawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTint(drawable, tint);
    DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_ATOP);

    return drawable;
}
like image 15
Nishanth Sreedhara Avatar answered Nov 13 '22 15:11

Nishanth Sreedhara