Load drawableLeft image for Button using databinding

It appears that you are passing in a resource ID to the android:drawableLeft attribute instead of a Drawable. By default android data binding will automatically convert integers to ColorDrawable because it assumes that they are colors.

There are a few ways to solve this. The first is to add a method:

public Drawable loadDrawable(Context context, int resourceId) {
    return context.getDrawable(resourceId);
}

and then bind it like this:

android:drawableLeft="@{MyUtil.loadDrawable(countryOfResidence.thumbnail)}"

You could also make thumbnail a Drawable instead of an int:

public final ObservableField<Drawable> thumbnail = new ObservableField<Drawable>();

You could also create your own BindingAdapter to accept an int argument. Follow the example in TextViewBindingAdapter:

@BindingAdapter({"android:drawableLeft"})
public static void setDrawableLeft(TextView view, int resourceId) {
    Drawable drawable = ContextCompat.getDrawable(view.getContext(), resourceId);
    setIntrinsicBounds(drawable);
    Drawable[] drawables = view.getCompoundDrawables();
    view.setCompoundDrawables(drawable, drawables[1], drawables[2], drawables[3]);
}

private static void setIntrinsicBounds(Drawable drawable) {
    if (drawable != null) {
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    }
}

If you do the above, you won't be able to use data binding to set an integer color as a drawable. If you want to separate it, you could use a different (app namespace) attribute. But you probably don't need to set color drawables as drawableLeft anyway.


If you have drawable represented as Int (DrawableRes) you can use this:

android:drawableStart="@{androidx.core.content.ContextCompat.getDrawable(context, config.icon)}"

Same can be done with color for example:

android:textColor="@{androidx.core.content.ContextCompat.getColor(context, config.iconColor)}"

Context is automatically defined in this case.


It is bit late answer but for future seekers If you can change your model

From

private int thumbnail;

to

private Drawable thumbnail;

Then you can pass drawable directly to layout instead of resource id

your model will become

public class CountryOfResidence {

private String countryName;
private Drawable thumbnail;


public CountryOfResidence(String countryName, Drawable thumbnail) {
    this.setCountryName(countryName);
    this.setThumbnail(thumbnail);
}
....

you can initialize your list like this

countryOfResidenceList = new ArrayList<>();
    countryOfResidenceList.add(new CountryOfResidence("Nigeria", ContextCompat.getDrawable(this, R.drawable.nigeria)));

and that is it send model to layout and load drawable normally like

<Button
                ...
                android:drawableLeft="@{countryOfResidence.thumbnail}"
                android:drawableStart="@{countryOfResidence.thumbnail}"
                android:text="@{countryOfResidence.countryName}"

                 />