Android Button Drawable Tint
Asked Answered
S

7

49

Is it possible to tint the drawableLeft in an android button? I have a black drawable I'd like to tint white. I know how to achieve this with an image view (image on the left) but I want to do this with the default android button.

enter image description here

My source code:

<Button android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:text="@string/drawer_quizzes"
        android:backgroundTint="@color/md_light_green_500"
        android:stateListAnimator="@null"
        android:textColor="#fff"
        android:textSize="12dp"
        android:fontFamily="sans-serif"
        android:drawableLeft="@drawable/ic_action_landscape"
        android:gravity="left|center_vertical"
        android:drawablePadding="8dp"
        />

Is there any way to tint the button? Or is there a custom view method to achieve this effect?

Sprint answered 19/6, 2015 at 12:50 Comment(3)
so you want to place an image on the left of the text in the button?Phthalein
@HawraaKhalil yes, exactly. But it should be tinted whiteSprint
Vote here code.google.com/p/android/issues/detail?id=198613 if you want drawableTint to go into support libraryOkwu
E
79

You can achieve coloring the drawableleft on a button with this method:

Step 1: Create a drawable resource file with bitmap as parent element as shown below and name it as ic_action_landscape.xml under the drawable folder

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@android:drawable/ic_btn_speak_now"
    android:tint="@color/white" />

Step 2: Create your Button control in your layout as below

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/md_light_green_500"
        android:drawableLeft="@drawable/ic_action_landscape"
        android:drawablePadding="8dp"
        android:fontFamily="sans-serif"
        android:gravity="left|center_vertical"
        android:stateListAnimator="@null"
        android:text="@string/drawer_quizzes"
        android:textColor="#fff"
        android:textSize="12dp" />

The button gets the drawable from the ic_action_landscape.xml from the drawable folder instead of @android:drawable or drawable png(s).

Method 2:
Step 1:
You can even add the icon as a Action Bar and Tab icons with Foreground as Image that can be imported from a custom location or a Clipart

Step 2:
Under Theme dropdown select Custom

Step 3:
Then select the color as #FFFFFF in the Foreground color selection. Method 2 Pictorial representation

Finally finish the wizard to add the image, then add the drawable as an image.

Pictorial representation for answer to the question

Excretory answered 19/6, 2015 at 20:0 Comment(8)
Thanks, i'm using the first method now as I'd also like to use the (black) icon in other parts of the ui.Sprint
Keep in mind though, that the tint attribute is only supported since Lollipop. For pre-Lollipop support, I used the following code to tint the button drawable programmatically: Drawable[] drawables = postButton.getCompoundDrawables(); Drawable wrapDrawable = DrawableCompat.wrap(drawables[0]); DrawableCompat.setTint(wrapDrawable, getResources().getColor(android.R.color.white));, using the support-v4 library.Anthropomorphosis
It seems method 1 only works for default icons(from android). If we add a new icon on our resources, it does not work on my end. Just a note.Rattletrap
android:backgroundTint="@color/md_light_green_500" its only above api level 23 not work in lolipopBadalona
This (method 1, in my case) also works if you want to change the drawable colour for a TextView.Panamerican
What is the problem you are facing @AnandSavjani? Let me see if I can assist you and make my answer better.Excretory
I am trying to set drawable tint but its now showing any tint effectAdvisedly
Thats nice hack. My app's minimum version is 21 so don't have to worry about below 21Donnettedonni
C
14

You can either use drawable filter or if your API>=M then you can simply

textView.compoundDrawableTintList = ColorStateList.valueOf(Color.WHITE)

or in XML,

android:drawableTint="@color/white"
Calcium answered 17/10, 2019 at 11:58 Comment(1)
android:drawableTint is the correct answer here. Thanks!Hatshepsut
S
8

I know there are lots of answers already, but non of them made me happy since I didn't want to have different drawables for different styles of elements.

So my solution was to set color filter in constructor like this:

int textColor = getTextColors().getColorForState(EMPTY_STATE_SET, Color.WHITE);
Drawable[] drawables = getCompoundDrawablesRelative();
for (Drawable drawable : drawables) {
    if (drawable != null) {
        drawable.setColorFilter(textColor, PorterDuff.Mode.SRC_ATOP);
    }
}

I used text color because this was what I need, but it can be replaced with custom attribute to be more dynamic.

Serology answered 20/6, 2017 at 10:11 Comment(0)
B
6

I was able to accomplish this same exact thing using a MaterialButton (from the material support library, which most people are probably using already). MaterialButton has an attribute named icon which can be placed left/center/right (default left). It also has an attribute called iconTint which will tint the icon.

Gradle:

implementation "com.google.android.material:material:1.1.0-alpha09"

View:

<com.google.android.material.button.MaterialButton
    android:layout_width="0dp"
    android:layout_weight="1"
    android:text="@string/drawer_quizzes"
    android:backgroundTint="@color/md_light_green_500"
    android:stateListAnimator="@null"
    android:textColor="#fff"
    android:textSize="12dp"
    android:fontFamily="sans-serif"
    app:icon="@drawable/ic_action_landscape"
    app:iconTint="@color/white"
    android:gravity="left|center_vertical"
    android:drawablePadding="8dp"
    />
Barmy answered 16/8, 2019 at 7:26 Comment(0)
G
2

As @Boris suggested, you can use the support library.

I have extended the AppCompatButton with some draft code. The TintAppCompatButton should have default behaviour but TintAppCompatButtonCustom was made to demo custom coloring.

I’ll see if I can raise a PR to get that into the official support library.

The code of interest is:

private void init() {
    PorterDuff.Mode tintMode = PorterDuff.Mode.SRC_IN;
    Drawable[] ds = getCompoundDrawables();
    tint(ds[LEFT], Color.RED, tintMode);
    tint(ds[TOP], Color.YELLOW, tintMode);
    tint(ds[RIGHT], Color.GREEN, tintMode);
    tint(ds[BOTTOM], Color.BLUE, tintMode);
}

private void tint(Drawable d, int color, PorterDuff.Mode tintMode) {
    TintInfo ti = new TintInfo();
    ti.mTintMode = tintMode;
    ti.mTintList = ColorStateList.valueOf(color);
    ti.mHasTintList = true;
    ti.mHasTintMode = true;

    TintManager.tintDrawable(d, ti, new int[]{0});
}
Greed answered 9/2, 2016 at 22:56 Comment(0)
B
0

I may be late on this but if you're using C#, you can do it this way:

Color iconColor = Color.Orange; // TODO: Get from settings
Mode mode = Mode.SrcAtop;

Drawable drawable = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.ic_action_arrest, null);

drawable.SetColorFilter(iconColor, mode);

You'll also need:

using Android.Graphics;
using static Android.Graphics.PorterDuff;
using Android.Graphics.Drawables;

Hope this helps. It's the easiest way I found. Note, too, that ANY place in your app that you are using this icon, it will be this color.

Birdella answered 26/7, 2016 at 19:8 Comment(0)
V
0

You can use android:drawableTint="@color/yourColor" in >23 android version.

Vittorio answered 1/10, 2018 at 13:39 Comment(4)
what about below 23??Cyndicyndia
for that you can use app:drawableTintMinaret
Weird, doesn't work for me in API 23.Banquer
@KishanSolanki, here doens't work in API 23Blackdamp

© 2022 - 2024 — McMap. All rights reserved.