I'm converting a project in Java to Kotlin and I'm surprise that interface made the code heavier in Kotlin than in Java.
Example:
I want to set the onBackPressListener in MainActivity from MyFragment.
File 1: MainActivity, File 2: MyFragment, File 3: OnBackPressedListener (Interface)
File 1 in Java, File 2 in Kotlin, File 3 in Java:
activity.setOnBackPressed { /* Do something */ }
File 1 in Kotlin, File 2 in Kotlin, File 3 in Java:
activity.setOnBackPressed(OnBackPressedListener { /* Do something */ })
File 1 in Kotlin, File 2 in Kotlin, File 3 in Kotlin:
activity.setOnBackPressed(object: OnBackPressedListener {
override fun onBackPressed() {
/* Do something */
}
})
Is it possible to have the 3 files in Kotlin and use lambda to set the listener ?
(This is so frustrating to get more code in Kotlin..)
Thanks
The lambda version works only when kotlin interop with java because SAM Conversions
, see the official documents.
Also note that this feature works only for Java interop; since Kotlin
has proper function types, automatic conversion of functions into
implementations of Kotlin interfaces is unnecessary and therefore
unsupported.
So if you want use lambda to set the listener with pure kotlin, you can define your listener
and setOnBackPressed
method like this:
var listener: (() -> Unit)? = null
fun setOnBackPressed(l: () -> Unit) {
listener = l
}
then invoke it by:
listener?.invoke()
You use Java style while use Kotlin =)
If you really want to use OnBackPressedListener
you can just wrap it in inline
function, like:
inline fun backPress(crossinline action:()->Unit):OnBackPressedListener {
return object: OnBackPressedListener {
override fun onBackPressed() {
action()
}
}
}
And then just set listener
activity.setOnBackPressed(backPress {
/* Do something */
})