Функции расширения Kotlin
Есть ли возможность использовать функцию расширения с привязкой данных? XML:
<data>
<import type="my.package.domain.country.model.City.streetName" />
<variable
name="city"
type="my.package.domain.country.model.City" />
</data>
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{city.street.streetName()}" />
my.package.domain.country.model.city
data class City(
val id: String,
val street: Street
)
fun City.streetName(): String = street.houseNumber
ошибка
[kapt] Возникла исключительная ситуация: android.databinding.tool.util.LoggedErrorException: обнаружены ошибки привязки данных. ****/ ошибка привязки данных ****msg: невозможно найти метод streetName() в классе my.package.domain.country.model.City
Спасибо;)
6 ответов
Вы должны сначала импортировать CityKt в XML
<import type="my.package.domain.country.model.CityKt" />
В разделе данных, то вы можете использовать его следующим образом
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{CityKt.streetName(city)}" />
Если вы просмотрите CityKt, вы увидите, что есть статический метод Java с первым аргументом City
Хотя @skiff2011 верен, можно также использовать alias
чтобы предотвратить Kt
постфикс.
Например, некоторая функция расширения находится в ExtensionFunctionsKt
может иметь псевдоним ExtensionFunctions
<import
alias="ExtensionFunctions"
type="com.helloworld.app.util.ExtensionFunctionsKt" />
<variable
name="someData"
type="com.helloworld.app.model.SomeData" />
В ExtensionFunction
псевдоним теперь можно использовать для вызова функции расширения. Первым аргументом по-прежнему должна быть переменная расширенного класса.
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{ExtensionFunctions.doStuff(someData)}" />
Функция расширения
Бывший:
fun Context.isDarkMode(): Boolean {
}
Теперь у нас есть функция расширения для темного режима, к которой можно получить доступ через контекст.
Обычно в классе Kotlin мы можем получить доступ с помощью context obj, как показано ниже.
context.isDarkMode()
Но в Xml мы не можем получить доступ, как указано выше.
Нам нужно импортировать функцию расширения, добавив KT к классу.
Пример. Если имя вашего файла - Extensions, то для импорта следует использовать ExtensionsKt.
Импортируйте, как показано ниже, в xml.
<import type="com.paytmmoney.core.extensions.ExtensionsKt" />
И затем мы можем получить доступ к функции расширения, как показано ниже, т.е. нам нужно передать объект, для которого мы создаем расширение, то есть в нашем случае это контекст.
app:context='@{(ExtensionsKt.isDarkMode(context)}'
Если вы используете класс Utils, вы можете:
object Utils(){
fun streetName(): String {}
}
<import
type="com.helloworld.app.util.Utils" />
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Utils.INSTANCE.streetName()}"
/>
Используйте модель представления для вызова функций расширения.
Привязка данных использует псевдо-Java-код в XML, поэтому вы не можете использовать функции расширения. Вы можете указать их для kotlin, но для java их нужно вызывать, как сказано в разделе Вызов Kotlin из Java.
Шаги могут быть (я не пробовал):
<import type="my.package.domain.country.model.CityKt" />
...
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{CityKt.streetName(city)}" />