Привязка данных: ObservableField со значением лямбда не компилируется
Я пытаюсь определить видимость View
вычисляя лямбду, которая принимает один параметр в качестве аргумента. Я использую Kotlin, кстати.
В моем ViewModel
Я имею:
val customerPropVisibility: ObservableField<(KProperty1<Customer, *>) -> Int> = ObservableField(
{ _ ->
// body of the lambda
})
Обязательное выражение для View
является следующим:
android:visibility="@{vm.customerPropVisibility.invoke(title)}"
vm
а также title
правильно объявлены как переменные в data
тег макета.
При компиляции я получаю две ошибки:
1) несовместимые типы: объект не может быть преобразован в Function1
2) несовместимые типы: объект не может быть преобразован в целое число
Существует только одна ошибка первого типа и несколько ошибок второго типа. Количество ошибок второго типа совпадает с количеством вызовов лямбды в XML-файле макета.
Мои попытки решить проблему:
Очевидно, что ошибка типа 1 может быть решена путем переопределения get()
метод ObservableField
(возвращая метод Function1
явно). Это работает, но уродливо и должно выполняться компилятором, когда он выводит тип для customerPropVisibility
, Определенно, что-то здесь не так.
Ошибка типа 2 для меня загадка, потому что тип функции (моя лямбда) явно возвращает Int.
Я предполагаю, что это как-то связано с совместимостью Kotlin / Java.
Если вы столкнулись с той же проблемой, пожалуйста, поделитесь опытом ее решения.
РЕДАКТИРОВАТЬ:
Поскольку эта ошибка еще не устранена, я использую немного другой подход для достижения того же результата:
Вместо установки значения ObservableField
лямбда, я установил его на функцию ссылки (::getVisibility
) вот так:
fun getVisibility(prop: KProperty1<*, *>): Int = propVisibilityValues[prop] ?: View.GONE
val propVisibilityGetter = ObservableField(::getVisibility)
И всякий раз, когда propVisibilityValues
изменения я уведомляю propVisibilityGetter
:
private val propVisibilityValues = ObservableArrayMap<KProperty1<*, *>, Int>().apply {
addOnMapChangedCallback(object : ObservableMap.OnMapChangedCallback<ObservableMap<KProperty1<*, *>, Int>, KProperty1<*, *>, Int>() {
override fun onMapChanged(p0: ObservableMap<KProperty1<*, *>, Int>?, p1: KProperty1<*, *>?) {
propVisibilityGetter.notifyChange()
}
})
}
В файле макета XML выражение привязки выглядит так:
android:visibility="@{vm.propVisibilityGetter.call(title)}"
Общий результат: грязный в модели представления, но чистые выражения привязки.