MLabar
MLabar

Reputation: 523

Android - Binding adapter not working

I have create a binding adapter to display picture with picasso, but it doesn't work. I have the following error :

Found data binding errors. ****/ data binding error ****msg:Cannot find the setter for attribute 'app:loadPicture' with parameter type java.lang.String on android.widget.ImageView. file:/home/groupevsc.com/mathieu_labar/Documents/Projects/android-jetpack/app/src/main/res/layout/activity_detail_movie.xml loc:27:31 - 27:52 ****\ data binding error ****

Here is my binding adapter :

object CommonBindingUtil {

    @JvmStatic
    @BindingAdapter("loadPicture")
    fun loadPicture(view: ImageView, text: String) {
        Picasso.with(view.context)
                .load(text)
                .error(R.drawable.ic_movie_24)
                .fit()
                .placeholder(R.drawable.ic_movie_24)
                .into(view)
    }

}

And my XML has attribute "app:loadPicture" :

<ImageView
    android:id="@+id/picture"
    android:layout_width="@dimen/material_image_simple_width"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    android:src="@drawable/ic_movie_24"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:loadPicture="@{viewModel.movie.Poster}"/>

Here is my GitHub repository: https://github.com/mlabar/android-jetpack/tree/tech_ajout_databinding

Would anyone have an idea to solve my problem?

Thank you!

Upvotes: 8

Views: 6842

Answers (4)

Muheeb Mehraj
Muheeb Mehraj

Reputation: 91

You are not passing the right parameters for binding adapter function.

object CommonBindingUtil {

    @JvmStatic
    @BindingAdapter("loadPicture")
    fun loadPicture(view: ImageView, text: String) {
        Picasso.with(view.context)
            .load(text)
            .error(R.drawable.ic_movie_24)
            .fit()
            .placeholder(R.drawable.ic_movie_24)
            .into(view)
    }
}

Here loadPicture function expects parameters imageView and a String, but here, in your xml your are passing the Object of photo

app:loadPicture="@{viewModel.movie.Poster}

You should instead write something like this app:loadPicture="@{viewModel.movie.Poster.url}

Upvotes: 0

MLabar
MLabar

Reputation: 523

Thank you @Blackbelt to solve my problem, i have added "kotlin-kapt" in all my build.gradle modules:

apply plugin: 'kotlin-kapt'

Upvotes: 27

fightingCoder
fightingCoder

Reputation: 594

Here is my code

@JvmStatic
    @BindingAdapter({"bind:loadPicture"})
    fun loadPicture(view: ImageView, loadPicture: String) {
        Picasso.with(view.context)
                .load(loadPicture)
                .error(R.drawable.ic_movie_24)
                .fit()
                .placeholder(R.drawable.ic_movie_24)
                .into(view)
    }

for more details see my project on GitHub

Upvotes: 2

HassanUsman
HassanUsman

Reputation: 1973

Change your MovieViewModel class like this:

class MovieViewModel(private val movie: Movie) : Observer, BaseObservable() {

    init {
       Movie.addObserver(this)
    }
    val Poster: String
        @Bindable get() {
            return Poster.name
        }
}

And Movie class like this:

class Movie: Observable() {
    var Title: String = ""
        set(value) {
            field = value
            setChangedAndNotify("Title")
        }
    var Year: String = ""
        set(value) {
            field = value
            setChangedAndNotify("Year")
        }
    var imdbID: String = ""
        set(value) {
            field = value
            setChangedAndNotify("imdbID")
        }
    var Type: String = ""
        set(value) {
            field = value
            setChangedAndNotify("Type")
        }
    var Poster: String = ""
        set(value) {
            field = value
            setChangedAndNotify("Poster")
        }
    var Plot: String = ""
        set(value) {
            field = value
            setChangedAndNotify("Plot")
        }

    private fun setChangedAndNotify(field: Any) {
        setChanged()
        notifyObservers(field)
    }
}

Make your class context according to your need, run it hope it'll solve your problem.

Upvotes: 0

Related Questions