18

I want to change my icon color from my button programmatically...

On my xml, i have:

            android:drawableTint="@color/colorPrimary"
            android:drawableTop="@drawable/ic_car_black_24dp"

To set the icon and set the icon color... But i want to change the icon color from my java side...

Can someone help me?

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/bt_search_vehicle_car"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/eight_density_pixel"
            android:layout_weight="1"
            android:background="@drawable/background_rounded_blue_border"
            android:drawableTint="@color/colorPrimary"
            android:drawableTop="@drawable/ic_car_black_24dp"
            android:padding="@dimen/eight_density_pixel"
            android:text="Carros"
            android:textAllCaps="false"
            android:textColor="@color/colorPrimary" />
Felipe A.
  • 929
  • 3
  • 12
  • 28

6 Answers6

20

First of all, do not use AppCompatButton directly unless you write a custom view and you want to extend it. The normal Button will be "resolved" by the system as AppCompatButton so you don't need the latter.

As for your original question, there are multiple ways to tint a drawable. You can use DrawableCompact to do it in a "tinting" fashion while you can use a normal ColorFilter to do this in a "filtering" fashion.

Tinting with DrawableCompat

Use DrawableCompat to wrap the drawable so it can be tinted on older platforms.

Button yourButton = findViewById(R.id.bt_search_vehicle_car);

Drawable drawable = getResources().getDrawable(R.drawable.ic_car_black_24dp);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable, getResources().getColor(R.color.colorPrimary));

yourButton.setCompoundDrawables(null, drawable, null, null);

Using ColorFilter

Use the Drawable.setColorFilter(...) method to set an overlaying color filter for your drawable.

Button yourButton = findViewById(R.id.bt_search_vehicle_car);

Drawable drawable = getResources().getDrawable(R.drawable.ic_car_black_24dp).mutate();
drawable.setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.SRC_ATOP);

yourButton.setCompoundDrawables(null, drawable, null, null);
Gergely Kőrössy
  • 5,620
  • 3
  • 28
  • 44
  • 1
    Well, the `setCompoundDrawables` only works when we configure rectangle bound. The workaround is using `setCompoundDrawablesWithIntrinsicBound` if we don't want to specify the bound explicitly. – mochadwi Mar 18 '19 at 02:18
12

Use setCompoundDrawableTintList property to change color i use it as following

btn_recent.setCompoundDrawableTintList(ColorStateList.valueOf(Color.parseColor("#ff9708"))); 
Usman Arshad
  • 153
  • 1
  • 10
5

I use vector drawable as drawableLeft for the Button and changed the button drawable colour programmatically using Kotlin like this.

button_id.compoundDrawableTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.blue))
Salman Nazir
  • 2,759
  • 2
  • 28
  • 42
3
public void setTextViewDrawableTintColor(TextView textView, int color) {
    for (Drawable drawable : textView.getCompoundDrawables()) {
        if (drawable != null) {
            drawable.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(textView.getContext(), color), PorterDuff.Mode.SRC_IN));
        }
    }
}
1

I've assumed that you need to change the android:drawableTint property.

According to this, you need to create a new drawable with a different tint, then change the drawable resource for your button.

Create a Drawable from your icon:

Drawable mDrawable=getContext().getResources().getDrawable(R.drawable.ic_car_black_24dp); 

Then change its tint:

mDrawable.setColorFilter(new PorterDuffColorFilter(0xffff00,PorterDuff.Mode.MULTIPLY));

One you've done this, set your new Drawable:

yourButton.setImageDrawable(mDrawable);

I suggest you to skim through the comments of the linked question and here in the docs to discover different PorterDuff modes.

magicleon94
  • 4,887
  • 2
  • 24
  • 53
  • I need to set a diferent image? I can't change only the color of the image? – Felipe A. Oct 12 '17 at 15:59
  • You need a different drawable to do this. I assume you need to change the `ic_car_black_24dp` icon, right? – magicleon94 Oct 12 '17 at 16:01
  • No, i just need to change the color of the ic_car_black_24dp... When i use drawableTint, i can change the color... but in xml... I didn't find any attribute to change this on java side – Felipe A. Oct 12 '17 at 16:02
  • Oh alright, my bad. Let me check some stuff and I will edit my answer – magicleon94 Oct 12 '17 at 16:03
  • Working on it... when i finish the implementation, i'll feedback you, just wait some minutes please – Felipe A. Oct 12 '17 at 16:24
  • i found this: setCompoundDrawablesWithIntrinsicBounds to change my drawable image... Now i need only to change the image... This method not working – Felipe A. Oct 12 '17 at 16:33
0

You might wanna check my approach to change button colour dynamically through data binding adapter with kotlin based on your question. Check it out here

I've also mentioned and reference the original answer also the article for an alternative solution or get a better understanding of the workaround

mochadwi
  • 1,190
  • 9
  • 32
  • 87