Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load drawableLeft image for Button using databinding

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?

like image 499
Ojonugwa Jude Ochalifu Avatar asked May 23 '17 21:05

Ojonugwa Jude Ochalifu


2 Answers

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.

like image 58
George Mount Avatar answered Oct 20 '22 09:10

George Mount


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.

like image 23
David Sucharda Avatar answered Oct 20 '22 09:10

David Sucharda