Kotlin Extension Functions Databinding

MvvmKotlinExtension Function

Mvvm Problem Overview


Is there any possibility to use extension function with a databinding? 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

Error

> [kapt] An exception occurred: > android.databinding.tool.util.LoggedErrorException: Found data binding > errors. > ****/ data binding error ****msg:cannot find method streetName() in class my.package.domain.country.model.City

Thanks ;)

Mvvm Solutions


Solution 1 - Mvvm

You have to import CityKt firstly into xml

<import type="my.package.domain.country.model.CityKt" />

int the data section then you can use it like this

<TextView
  android:id="@+id/city"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="@{CityKt.streetName(city)}" />

If you review CityKt you will see that there is static Java method with City as first argument

Solution 2 - Mvvm

While @skiff2011 is correct, one could also use alias to prevent the Kt postfix.

For example, a certain extension function is located in ExtensionFunctionsKt can be aliased by ExtensionFunctions

<import
    alias="ExtensionFunctions"
    type="com.helloworld.app.util.ExtensionFunctionsKt" />

<variable
    name="someData"
    type="com.helloworld.app.model.SomeData" />

The ExtensionFunction alias can now be used to call the extension function. The first argument still needs to be the extended class variable.

<TextView
    android:id="@+id/city"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{ExtensionFunctions.doStuff(someData)}" />

Solution 3 - Mvvm

Extension function

Ex:

fun Context.isDarkMode(): Boolean {

 }

Now we have Extenstion function for dark mode which can be accessed using context.

Usually in Kotlin class we can access using context obj like below.

context.isDarkMode()

But in Xml,we can't access like above.

We need to import Extension function by appending KT to class.

Ex) If your file name is Extensions,then import should be ExtensionsKt.

Import like below in xml.

 <import type="com.paytmmoney.core.extensions.ExtensionsKt" />

And then we can access Extension function like below i.e we need to pass object for which we are creating Extension i.e in our case it is context.

  app:context='@{(ExtensionsKt.isDarkMode(context)}'

Solution 4 - Mvvm

If using Utils class you can to this:

 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()}"
              />

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2725105View Question on Stackoverflow
Solution 1 - Mvvmskiff2011View Answer on Stackoverflow
Solution 2 - MvvmTom SabelView Answer on Stackoverflow
Solution 3 - MvvmTarun AView Answer on Stackoverflow
Solution 4 - MvvmErfan EghterafiView Answer on Stackoverflow