Search code examples
androidkotlinmvvmandroid-databindingandroid-viewmodel

How to databind imageview with drawable in viewmodel?


Binding Adapter:

@BindingAdapter("src")
fun loadImage(imageView: ImageView, src: Any) {

    if (src is Int || src is String || src is Drawable) {
        Glide.with(imageView.context).load(src).into(imageView)
    }
}

Imageview in xml:

<androidx.appcompat.widget.AppCompatImageView
    android:layout_width="200dp"
    android:layout_height="300dp"
    app:src="@{model.image}" />

View model:

val image = MutableLiveData<Drawable>()

init {
    // image.value = How to initialize this?
}

Scenario:
I want to bind imageview with drawable received from server. I want to set a placeholder drawable till the image is obtained from server.

Error for the above code:

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter src

Note: 1. Please provide a solution which follows MVVM. (No context in viewmodel)


Solution

  • Extending @Reaz Murshed's idea and after refering Android Binding Adapter Docs, I created a binding adapter for all imageview's. (All imageview's need not have the same placeholder)

    Binding Adapter:

    @BindingAdapter(value = ["src", "placeholderImage"], requireAll = false)
    fun loadImage(imageView: ImageView, src: Int?, placeholderImage: Drawable?) {
        if (placeholderImage != null) {
            Glide.with(imageView.context).load(src).placeholder(placeholderImage).into(imageView)
        } else {
            Glide.with(imageView.context).load(src).into(imageView)
        }
    }
    
    @BindingAdapter(value = ["src", "placeholderImage"], requireAll = false)
    fun loadImage(imageView: ImageView, src: String?, placeholderImage: Drawable?) {
        if (placeholderImage != null) {
            Glide.with(imageView.context).load(src).placeholder(placeholderImage).into(imageView)
        } else {
            Glide.with(imageView.context).load(src).into(imageView)
        }
    }
    
    @BindingAdapter(value = ["src", "placeholderImage"], requireAll = false)
    fun loadImage(imageView: ImageView, src: Drawable?, placeholderImage: Drawable?) {
        if (placeholderImage != null) {
            Glide.with(imageView.context).load(src).placeholder(placeholderImage).into(imageView)
        } else {
            Glide.with(imageView.context).load(src).into(imageView)
        }
    }
    

    XML:

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="200dp"
        android:layout_height="300dp"
        app:placeholderImage="@{@drawable/kids_ethnic_1}"
        app:src="@{model.image}" />
    

    If needed we can add other methods to make placeholder of Int or other datatype as required.