Reputation: 1364
I was wondering if it is possible to pass onClik
[handling onClick
] through callbackFlow
as I saw from this this post.
I was having hard time implementing since the onClick Callback
was inside parameter also Button
is function so wasn`t able to implement extension function
anyways I tried something like
lateinit var buttonListener :Flow<Unit>
fun <T >offers(t: T) = callbackFlow {
offer(t)
awaitClose { null }
}
CoroutineScope(IO).launch {
if(::buttonListener.itInitalized){
buttonListener.collect {
println("it => Kotlin.Unit")
}
}
}
MaterialTheme {
Button(
onClick = {
println("buttonClicked")
buttonListener = offers(Unit)
} //...
) { /** designs */}
}
which is callable only 1 times on every runtime
buttonClicked <--\
Kotlin.Unit => Kotlin.Unit <--/\__first click
buttonClicked
buttonClicked
buttonClicked
yet expecting someting like
buttonClicked
Kotlin.Unit => Kotlin.Unit
buttonClicked
Kotlin.Unit => Kotlin.Unit
buttonClicked
Kotlin.Unit => Kotlin.Unit
Upvotes: 1
Views: 657
Reputation: 1674
You can use coroutine Channel
instead of Flow
to receive events from outside the coroutine. Then convert it to Flow
using consumeAsFlow()
method.
Now the flow operators like collect
can be called on this Flow
.
It can receive multiple onClick
events from the button composable.
var buttonListener = Channel<Unit>()
CoroutineScope(Dispatchers.IO).launch {
buttonListener.consumeAsFlow().collect {
Log.d(TAG, "onCreate: $it => Kotlin.Unit")
}
}
MaterialTheme {
Button(
onClick = {
Log.d(TAG, "onCreate: buttonClicked")
buttonListener.offer(Unit)
}
){
Text(text = "Button")
}
}
Upvotes: 1