Не удается найти получатель для атрибута ImageView при использовании привязки данных в kotlin - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь изучить привязку данных с помощью Kotlin , и мне удалось успешно реализовать его для редактирования текста и текстовых представлений.После этого я пытаюсь использовать его для просмотра изображений.В настоящее время я пытаюсь предоставить пользователям возможность выбрать фотографию своего профиля, нажав на изображение.Этот код работает правильно, но когда я пытаюсь установить изображение для представления с помощью адаптера привязки данных, я получаю следующую ошибку:

Обнаружены ошибки привязки данных.**** / ошибка привязки данных **** msg: не удается найти получатель для атрибута 'android: userImage' с типом значения java.lang.String в de.hdodenhof.circleimageview.CircleImageView.file: /home/parangat-pt-p10/AndroidStudioProjects/ReUsableAndroid/reusable_android/app/src/main/res/layout/activity_signup.xml loc: 25: 12 - 31:48 **** \ ошибка привязки данных ****

Ниже приведен мой код для того же.

Код компоновки ImageView

<de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="center_horizontal"
            android:userImage="@{signup.userImage}"
            android:id="@+id/iv_user"
            android:src="@drawable/profile"/>

Код класса модели

    class Signup {
    var userImage=""
    var firstName=""
    var lastName=""
    var phoneNumber=""
    var postCode=""
    var country=""
    var email=""
    var password=""
    var confirmPassword=""
    var isAcceptTerms=false

    @BindingAdapter("android:userImage")
    fun loadImage(view: CircleImageView, imageUrl: String) {
        userImage=imageUrl
        Glide.with(view.context).load(imageUrl).into(view)

    }
}

И это то, что я делаю после того, как пользователь выбрал изображение

override fun onSingleImageSelected(uri: Uri?) {
    signupBinding.signup?.loadImage(iv_user,uri.toString())

}

Поскольку это написано в kotlin, поэтому нет необходимости определять методы getter и setter.но ошибка говорит о том, что метод получения не найден.

Как и предполагал Энзоки, я создал адаптер привязки в отдельном файле, как показано ниже

@BindingAdapter("userImage")
fun loadImage(view: CircleImageView, imageUrl: String) {
    Glide.with(view.context).load(imageUrl).into(view)
}

Но у меня все еще остается та же проблема.

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Используйте это

@BindingAdapter({"bind:userImage"})

Вместо этого

@BindingAdapter("android:userImage")

И в CircleImageView

<de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="center_horizontal"
            app:userImage="@{signup.userImage}"
            android:id="@+id/iv_user"
            android:src="@drawable/profile"/>

вот хорошая статья для Loading images with data binding

0 голосов
/ 11 октября 2018

Правильный подход

  • Используйте либо Наблюдаемые / Живые данные .
  • Создайте класс адаптера привязки индивидуально и не путайте вещи в модели.
    • Да, учебники делают это, потому что они просто учат вас.
    • Просто создайте один общий адаптер привязки (например, android:src) для всего приложения.
  • Нет необходимости использовать пользовательское пространство имен, пока оно вам не понадобится.Таким образом, вы можете использовать android:src вместо android:userImage.
  • Не нужно использовать CircleImageView в BindingAdapter, создайте общий адаптер с ImageView, поскольку CircleImageView является дочерним для ImageView.

Окончательный код

  • Если вам нужно вручную изменить поля, например signup.userImage = "someUrl", тогда используйте Bindable и notify, в остальном нет необходимости в обоих.
  • Если вы используете ObservableField вместо расширения класса BaseObservable, вам не нужно использовать Bindable и notify.

Registration.class

class Signup : BaseObservable() {
    @get:Bindable
    var userImage: String = ""
        set(value) {
            field = value
            notifyPropertyChanged(BR.userImage)
        }
}

DataBindingAdapter.kt

 // binding adapter for setting url/uri on ImageView
@BindingAdapter("android:src")
fun setImageUrl(view: ImageView, url: String) {
    Glide.with(view.context).load(url).into(view)
}

layout.xml

<de.hdodenhof.circleimageview.CircleImageView
            ...
            android:src="@{signup.userImage}"/>

Теперь вы можете установитьbinding.signup.userImage = "Url", он автоматически преломляется в пользовательском интерфейсе.

Вот и все!

Причина сбоя

Когда вы используете привязку данных и хотите автоматическое обновление интерфейса после установки полей,тогда ваша модель должна быть одной из следующих:

В вашем случае изначально ваш URL пуст ("").Теперь, когда вы устанавливаете изображение через некоторое время программно, пользовательский интерфейс не уведомляется, потому что вы не используете какой-либо параметр наблюдения, как я сказал выше.

Немного больше информации

Разница между ними заключается в том, что Livedata is Android Lifecycle Aware (Activity / Fragments / Services).

LiveData - это наблюдаемый класс держателя данных.В отличие от обычной наблюдаемой, LiveData учитывает жизненный цикл, то есть он учитывает жизненный цикл других компонентов приложения, таких как действия, фрагменты или службы.Эта осведомленность гарантирует, что LiveData обновляет только те компоненты приложения, которые находятся в активном жизненном цикле.

0 голосов
/ 11 октября 2018

попробуйте удалить андроид TAG

@BindingAdapter("userImage")
fun loadImage(view: CircleImageView, imageUrl: String) {
    userImage=imageUrl
    Glide.with(view.context).load(imageUrl).into(view)

}

И

<de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        app:userImage="@{signup.userImage}"
        android:id="@+id/iv_user"
        android:src="@drawable/profile"/>
...