I have a Button that has an Icon and a text.
This is achieved with this code:
<Button
...
android:drawableLeft="@drawable/ghana"
android:drawableStart="@drawable/ghana"
android:text="@string/hint_ghana"
/>
Databinding works with the text but not with the icon when I do this:
<Button
...
android:drawableLeft="@{countryOfResidence.thumbnail}"
android:drawableStart="@{countryOfResidence.thumbnail}"
android:text="@{countryOfResidence.countryName}"
/>
This is the result:
I have looked for a solution to this but can't find any as most are focused on loading an image into and ImageView.
My Model class looks like this:
public class CountryOfResidence {
private String countryName;
private int thumbnail;
public CountryOfResidence(String countryName, int thumbnail) {
this.setCountryName(countryName);
this.setThumbnail(thumbnail);
}
....
In the onCreate()
method of the calling Activity, am doing this
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivitySignUpBinding signUpBinding = DataBindingUtil.setContentView(this, R.layout.activity_sign_up);
MyHandler myHandler = new MyHandler();
signUpBinding.setMyHandler(myHandler);
mViewFlipper = (ViewFlipper) findViewById(R.id.signUpViewFlipper);
countryOfResidenceList = new ArrayList<>();
countryOfResidenceList.add(new CountryOfResidence("Nigeria", R.drawable.nigeria));
countryOfResidenceList.add(new CountryOfResidence("Ghana", R.drawable.ghana));
countryOfResidenceList.add(new CountryOfResidence("Kenya", R.drawable.kenya));
signUpBinding.setCountryOfResidence(countryOfResidenceList.get(1));
Finally, the data tag in my layout looks like this
<data>
...
<variable
name="countryOfResidence"
type="orem_tech.com.teylur.model.CountryOfResidence"/>
</data>
Any advice?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With