Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write Composable function using Kotlin Functional (SAM) Interface

We can write functional interfaces in Kotlin like this - function-interfaces

fun interface Sum {
    fun add(a: Int, b: Int): Int
}

val sumImpl = Sum { a, b ->
    return@Sum a + b
}

val testSum = sumImpl.add(4, 5)

How can we write Jetpack Composable function in same way? Below code is not working. `

fun interface SampleText {
    @Composable
    fun text(data : String)
}

val textImpl = SampleText { data ->
    return@SampleText @Composable { Text(data) }
}

@Composable
fun testText() = textImpl.text("Data")

I have tried this as well, but this also didn't work.

fun interface SampleText {
    fun text(data : String) : @Composable () -> Unit
}

val textImpl = SampleText { data ->
    @Composable { Text(data) }
}

@Composable
fun testText() = textImpl.text("Data")
like image 561
virat Avatar asked Oct 28 '25 14:10

virat


1 Answers

The first version is not compiling in its lambda form because your interface function returns a Unit and your'e actually having a Type mismatch error, its just weird the compiler reports Internal Error when you try to return a @Composable annotated function, but the issue becomes clear if you simply return something like a String.

enter image description here vs enter image description here

To solve your first version, either you fully declare an object of the class like this (though its useless since you want a lambda version of your SAM interface not an actual object in the first place)

val textImpl = object: SampleText {
    
    @Composable
    override fun text(data: String) {
        Text(data)
    }
}

, but it will work just by simply calling the testText() function like this.

testText()

Or change it to your second version.


Now for your second version, since your interface returns a @Composable lambda, you have to invoke it as well in the call-site, making two function invocations to make it work,

testText()() // two invocations

first call invokes your testText() function, second pair of parenthesis invokes the @Composable lambda from your interface.

Or simply call .invoke()

testText().invoke() // just call the .invoke() of the returned composable lambda

Either of the implementations and calls display the text "Data"

enter image description here

like image 175
z.g.y Avatar answered Oct 31 '25 05:10

z.g.y



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!