Функция высшего порядка в BindingAdapter

Я использую DataBinding в Android, и у меня есть собственное представление: CarouselView

Я написал для этого адаптер привязки:

@BindingAdapter("onClick")
fun setOnClick(carouselView: CarouselView, onClick: (position: Int) -> Unit) {
    carouselView.setImageClickListener { position ->
        onClick.run(position)
    }
}

И в xml:

<com.synnapps.carouselview.CarouselView
            android:id="@+id/carouselView"
            ...
            app:onClick="@{(p) -> vm.onAdsClicked(p)}"/>

Но не компилируется. Итак, я увидел этот ответ в переполнение стека. Но моя проблема в том, что я не могу использовать Runnable вместо функции kotlin hoc, потому что мне нужно передать параметр для работы.

Как я могу это решить?


person Saman Sattari    schedule 13.02.2019    source источник


Ответы (2)


Если позволите, у меня была та же проблема (передача параметра внутри HOF в BindingAdapter), и я придумал более элегантное решение. Вы можете заставить это работать, вам просто нужно сначала определить HOF как переменную.

Модель представления:

val onAdsClicked = fun(position: Int) {
// Do stuff
}

XML:

<com.synnapps.carouselview.CarouselView
            android:id="@+id/carouselView"
            ...
            app:onClick="@{vm.onAdsClicked}"/>

Адаптер привязки:

@BindingAdapter("onClick")
fun setOnClick(carouselView: CarouselView, onClick: (position: Int) -> Unit) {
    carouselView.setImageClickListener { position ->
        onClick(position)
    }
}
person Bogdan Zurac    schedule 05.03.2019
comment
но я не понимаю, как передать этот параметр в xml? - person Saman Sattari; 05.03.2019
comment
Я не совсем уверен, что понимаю ваш вопрос. Если вы имеете в виду передачу параметра position внутри XML, вам это не нужно. Он автоматически передается BindingAdapter. ЛЭ: Ох, как плохо, я забыл стереть вызов run() на лямбда-выражении. Попробуй. - person Bogdan Zurac; 06.03.2019
comment
К вашему сведению, добавлена ​​задача для отслеживания в средстве отслеживания проблем DataBinding по адресу issuetracker.google.com/issues/131663967. - person Bogdan Zurac; 30.04.2019
comment
У меня есть проблема, когда я использую этот подход, мои значения livedata стираются. - person Andrew; 14.09.2020

У меня сработало переключение с hoc func на прослушиватель этого пользовательского представления:

import com.synnapps.carouselview.ImageClickListener

@BindingAdapter("onClick")
fun setOnClick(carouselView: CarouselView, imageClickListener: ImageClickListener) {
    carouselView.setImageClickListener(imageClickListener)
}
person Saman Sattari    schedule 13.02.2019
comment
@Андрей app:onClick="@{(p) -> vm.onAdsClicked(p)}" - person Saman Sattari; 14.09.2020
comment
И как именно вы определяете слушателя в модели представления? Разве вы не получили бы ссылку на представление и, следовательно, не нарушили бы все намерения модели представления? А что такое п? - person Andrew; 14.09.2020
comment
@Андрей, нет. если вы видите, что я просто прохожу позицию. не просмотр. поэтому код в VM — это просто функция с именем onAdsClicked с одним параметром: position: Int - person Saman Sattari; 16.09.2020