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}"
/>