问题描述
我曾经使用Channel
将点击事件从Anko View类发送到Activity类,但是越来越多的Channel
函数被标记为已弃用.所以我想开始使用Flow
api.
I used to use Channel
to send out click event from Anko View class to Activity class, however more and more Channel
functions are marked as deprecated. So I wanted to start using Flow
apis.
我在下面迁移了代码:
private val btnProduceChannel = Channel<Unit>()
val btnChannel : ReceiveChannel<Unit> = btnProduceChannel
// Anko
button {
onClick {
btnProduceChannel.send(Unit)
}
}
收件人:
lateinit var btnFlow: Flow<Unit>
private set
button {
btnFlow = flow {
onClick {
emit(Unit)
}
}
}
我现在必须将流属性标记为var
,它不像以前那样优雅.这样对吗?定义属性时可以像Flow
一样初始化Rx Subject
吗?
I have to mark flow properties as var
now which is not so elegant as before. Is this way right? Can I init a Rx Subject
like Flow
when defining the property?
我拿回Channel
,然后用consumeAsFlow()
:
private val btnChannel = Channel<Unit>()
// This can be collected only once
val btnFlow = btnChannel.consumeAsFlow()
// Or add get() to make property can be collected multiple times
// But the "get()" can be easily forgotten and I don't know the performance of create flow every access
val btnFlow get() = btnChannel.consumeAsFlow()
// Send event with btnChannel
这似乎比lateinit var
好,但是有什么方法可以完全摆脱Channel
? (尽管Flow
本身像callbackFlow
,channelFlow
一样使用频道)
This seems better than lateinit var
one, but any way to get rid of Channel
completely? (Though Flow
itself like callbackFlow
, channelFlow
are using channel)
推荐答案
尽管我没有在项目中使用Anko,但是我已经编写了此函数与常规按钮引用一起使用,请查看它是否对您有帮助:
Although I don't use Anko in my project, I've written this function to use with regular button references, see if it helps you:
fun View.clicks(): Flow<Unit> = callbackFlow {
setOnClickListener {
offer(Unit)
}
awaitClose { setOnClickListener(null) }
}
可能的用法示例是:
button.clicks()
.onEach { /*React on a click event*/ }
.launchIn(lifecycleScope)
这篇关于Android按钮单击事件的Kotlin协程流程示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!