Load drawableLeft image for Button using databinding

Viewed 4961

I have a Button that has an Icon and a text.

enter image description here

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:

enter image description here

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?

4 Answers

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

                 />

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.

create BindingAdapter to all TextViews like this

@BindingAdapter("setDrawableRight")
fun TextView.setDrawableRight(resourceId: Int) {
    val drawable = ContextCompat.getDrawable(context, resourceId)
    setIntrinsicBounds(drawable)
    val drawables = compoundDrawables
    setCompoundDrawables(drawables[0], drawables[1], drawable, drawables[3])
}

private fun setIntrinsicBounds(drawable: Drawable?) {
    drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
}

and use in this way

app:setDrawableRight="@{R.drawable.ic_check_24}"

Thanks to George Mount

Related