Android: obtain ImageView's src from code
2024-01-11 01:17

I have an ImageView whose resource ID should be calculated based on some logic in the view model. So, I'd like to do something like this:

< ImageView android:src="@{viewModel.icon}" /> @Bindable public int getIcon() { switch (foo) { case BAR: return R.drawable.bar; ... } }

However, this code does not work. android:src is expecting a Drawable instead of an int. I am aware of setImageResource() but I don't want to use it. I want to stick to the principle that "the view is a function of the view model", i.e. no side effects.

I have tried context.getResources().getDrawable(resourceId) and it worked. But it's a little clumsy since I need to keep a context around, either in the view model or as a global/static reference, although it looks like it's still within the realm of the model view paradigm.

Is anyone aware of an elegant solution? Thanks.



Answer 1 :

This might get solve your problem.

object BindingAdapters { @BindingAdapter("android:src") fun setSrcCompat(imageView: ImageView, resId: Int) { imageView.setImageResource(resId) } }

Binding Adapters


other answer :

In Android Data Binding, you cant directly bind an int resource ID to android:src attribute, as it expects a Drawable. To overcome this, you can use a custom BindingAdapter to convert the resource ID to a Drawable before setting it to the ImageView. Heres how you can do it:

First, create a custom binding adapter class. In your app module, create a class like this:

javaimport android.widget.ImageView; import androidx.databinding.BindingAdapter; import androidx.core.content.ContextCompat; public class BindingAdapters { @BindingAdapter("app:srcCompat") public static void setImageResource(ImageView imageView, int resource) { imageView.setImageResource(resource); } @BindingAdapter("app:srcCompat") public static void setImageDrawable(ImageView imageView, int resource) { imageView.setImageDrawable(ContextCompat.getDrawable(imageView.getContext(), resource)); } }

Next, make sure to include this class in your layout XML. In your layout file, add the following attribute to the root layout:

xmlxmlns:app="http://schemas.android.com/apk/res-auto"

Now, you can use your custom binding adapter in the layout:

xml< ImageView app:srcCompat="@{viewModel.icon}" />

With this setup, when you set viewModel.icon to a resource ID, the custom binding adapter will convert it to a Drawable using ContextCompat.getDrawable().

Remember to include the BindingAdapters class in your module, and make sure your layout is set up for data binding.

This approach allows you to keep the logic in your view model while maintaining separation of concerns in the MVVM pattern.