user375566
user375566

Reputation:

How to programmatically set drawableLeft on Android button?

I'm dynamically creating buttons. I styled them using XML first, and I'm trying to take the XML below and make it programattic.

<Button
    android:id="@+id/buttonIdDoesntMatter"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:text="buttonName"
    android:drawableLeft="@drawable/imageWillChange"
    android:onClick="listener"
    android:layout_width="fill_parent">
</Button>

This is what I have so far. I can do everything but the drawable.

linear = (LinearLayout) findViewById(R.id.LinearView);
Button button = new Button(this);
button.setText("Button");
button.setOnClickListener(listener);
button.setLayoutParams(
    new LayoutParams(
        android.view.ViewGroup.LayoutParams.FILL_PARENT,         
        android.view.ViewGroup.LayoutParams.WRAP_CONTENT
    )
);      

linear.addView(button);

Upvotes: 539

Views: 336466

Answers (14)

aminography
aminography

Reputation: 22832

Kotlin Version

Use below snippet to add a drawable left to the button:

val drawable = ContextCompat.getDrawable(context, R.drawable.ic_favorite_white_16dp)
button.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

Important Point in Using Android Vector Drawable

When you are using an android vector drawable and want to have backward compatibility for API below 21, add the following codes to:

In app level build.gradle:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

In Application class:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    }

}

Upvotes: 40

gnganapath
gnganapath

Reputation: 947

myEdtiText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

Upvotes: 29

Maifee Ul Asad
Maifee Ul Asad

Reputation: 4607

Try this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
     fillButton[i].setBackground(getBaseContext().getResources().getDrawable(R.drawable.drawable_name));
}
else {
    fillButton[i].setBackgroundColor(Color.argb(255,193,234,203));
}

Upvotes: 0

Varun
Varun

Reputation: 33983

You can use the setCompoundDrawables method to do this. See the example here. I used this without using the setBounds and it worked. You can try either way.

UPDATE: Copying the code here incase the link goes down

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
img.setBounds(0, 0, 60, 60);
txtVw.setCompoundDrawables(img, null, null, null);

or

Drawable img = getContext().getResources().getDrawable(R.drawable.smiley);
txtVw.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);

or

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

Upvotes: 1225

Gibolt
Gibolt

Reputation: 47059

Add a Kotlin Extension

If you are going to be doing this frequently, adding an extension makes your code more readable. Button extends TextView; use Button if you want to be more narrow.

fun TextView.leftDrawable(@DrawableRes id: Int = 0) {
    this.setCompoundDrawablesWithIntrinsicBounds(id, 0, 0, 0)
}

To use the extension, simply call

view.leftDrawable(R.drawable.my_drawable)

Anytime you need to clear, don't pass a param or make another extension called removeDrawables

Upvotes: 4

Shaon
Shaon

Reputation: 2724

Worked for me. To set drawable at the right

tvBioLive.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close_red_400_24dp, 0)

Upvotes: 11

Mete
Mete

Reputation: 2884

If you are using drawableStart, drawableEnd, drawableTop or drawableBottom; you must use "setCompoundDrawablesRelativeWithIntrinsicBounds"

edittext.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.anim_search_to_close, 0)

Upvotes: 11

Rajneesh Shukla
Rajneesh Shukla

Reputation: 1382

Following is the way to change the color of the left icon in edit text and set it in left side.

 Drawable img = getResources().getDrawable( R.drawable.user );
img.setBounds( 0, 0, 60, 60 );
mNameEditText.setCompoundDrawables(img,null, null, null);

int color = ContextCompat.getColor(this, R.color.blackColor);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    DrawableCompat.setTint(img, color);

} else {
    img.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}

Upvotes: 3

user2969017
user2969017

Reputation: 33

Try this:

((Button)btn).getCompoundDrawables()[0].setAlpha(btn.isEnabled() ? 255 : 100);

Upvotes: -8

Muhaiminur Rahman
Muhaiminur Rahman

Reputation: 3152

Might be helpful:

TextView location;
location=(TextView)view.findViewById(R.id.complain_location);
//in parameter (left,top,right,bottom) any where you wnat to put
location.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.arrow,0);

Upvotes: 4

ישו אוהב אותך
ישו אוהב אותך

Reputation: 29783

as @Jérémy Reynaud pointing out, as described in this answer, the safest way to set the left drawable without changing the values of the other drawables (top, right, and bottom) is by using the previous values from the button with setCompoundDrawablesWithIntrinsicBounds:

Drawable leftDrawable = getContext().getResources()
                          .getDrawable(R.drawable.yourdrawable);

// Or use ContextCompat
// Drawable leftDrawable = ContextCompat.getDrawable(getContext(),
//                                        R.drawable.yourdrawable);

Drawable[] drawables = button.getCompoundDrawables();
button.setCompoundDrawablesWithIntrinsicBounds(leftDrawable,drawables[1],
                                               drawables[2], drawables[3]);

So all your previous drawable will be preserved.

Upvotes: 4

Jignesh Ansodariya
Jignesh Ansodariya

Reputation: 12685

Simply you can try this also

txtVw.setCompoundDrawablesWithIntrinsicBounds(R.drawable.smiley, 0, 0, 0);

Upvotes: 134

user1564762
user1564762

Reputation: 825

I did this:

 // Left, top, right, bottom drawables.
            Drawable[] drawables = button.getCompoundDrawables();
            // get left drawable.
            Drawable leftCompoundDrawable = drawables[0];
            // get new drawable.
            Drawable img = getContext().getResources().getDrawable(R.drawable.ic_launcher);
            // set image size (don't change the size values)
            img.setBounds(leftCompoundDrawable.getBounds());
            // set new drawable
            button.setCompoundDrawables(img, null, null, null);

Upvotes: 6

swapnil saha
swapnil saha

Reputation: 1320

For me, it worked:

button.setCompoundDrawablesWithIntrinsicBounds(com.example.project1.R.drawable.ic_launcher, 0, 0, 0);

Upvotes: 24

Related Questions