我正在 Android 上開發,在我的源代碼中有很多基于回呼的偵聽器。我想將其中的一部分轉換為 kotlin 流。我閱讀了很多關于回呼流的文章,但我認為這對我來說不是正確的選擇。
就我而言,有這樣的事情:
interface ActionListener{
public void actionStarted(actionId:Int)
public void actionProgress(actionId:Int, elementCreated:ExampleElement)
public void actionEnd(actionId:Int)
}
class MainProductor{
ActionListener actionListener;
MainProductor(ActionListener actionListener){
this.actionListener = actionListener
}
void start(){
//start some heavy works that start to call actionListener
}
}
用例:當我呼叫 start 某些 id 的動作開始并開始創建一些 ExampleElement 在 UI 中,我必須顯示由 id A 和 id B 的動作生成的 ExampleElement 串列。
在 UI 中,我必須在兩個動作之一開始時顯示一個進度,直到兩個 actionId 生成的所有元素都被創建,(這部分太棘手了)
如何繼續使用此 ActionListener 并使其適應新的 kotlin 流程?有可能嗎?
uj5u.com熱心網友回復:
使用的要點是callbackFlow它會在啟動/取消時自動注冊和注銷監聽器。處理多個回呼方法的可能解決方案是創建相應的事件類并發出它們。
sealed interface ActionListenerEvent {
class Started(val actionId: Int) : ActionListenerEvent
class ProgressChanged(val actionId: Int, val progress: Float, val elementCreated: ExampleElement) : ActionListenerEvent
class Finished(val actionId: Int) : ActionListenerEvent
}
fun actionEvents() = callbackFlow {
val listener = object : ActionListener {
override fun actionStarted(actionId: Int) {
trySend(ActionListenerEvent.Started(actionId))
}
override fun actionProgress(actionId: Int, progress: Float, elementCreated: ExampleElement) {
trySend(ActionListenerEvent.ProgressChanged(actionId, progress, elementCreated))
}
override fun actionEnd(actionId: Int) {
trySend(ActionListenerEvent.Finished(actionId))
}
}
registerListener(listener)
awaitClose {
unregisterListener(listener)
}
}
如果您想要一個能夠更好地控制您的偵聽器何時注冊/取消注冊的解決方案,您還可以使用MutableSharedFlow來公開事件。
class MainProductor{
val events = MutableSharedFlow<ActionListenerEvent>() // may need to configure replay and buffer depending on your specific use case
private val listener = object : ActionListener {
override fun actionStarted(actionId: Int) {
events.tryEmit(ActionListenerEvent.Started(actionId))
}
override fun actionProgress(actionId: Int, progress: Float, elementCreated: ExampleElement) {
events.tryEmit(ActionListenerEvent.ProgressChanged(actionId, progress, elementCreated))
}
override fun actionEnd(actionId: Int) {
events.tryEmit(ActionListenerEvent.Finished(actionId))
}
}
fun start(){
registerListener(this.listener)
}
fun stop(){
unregisterListener(this.listener)
}
}
編輯:示例用法
盡管我不完全確定預期的行為,尤其是如何處理該elementCreated: ExampleElement部分,但我假設您希望顯示當前正在運行的操作及其各自進度的串列。將事件聚合到這樣的串列中可能如下所示:
data class RunningAction(val id: Int, val progress: Float)// TODO integrate "elementCreated"
fun collectEvents() = flow {
val runningActions = mutableMapOf<Int, RunningAction>()
actionEvents().collect { event ->
when (event) {
is ActionListenerEvent.Started -> {
runningActions[event.actionId] = RunningAction(id = event.actionId, progress = 0f)
}
is ActionListenerEvent.ProgressChanged -> {
val action = runningActions[event.actionId]
if(action != null){
runningActions[event.actionId] = action.copy(progress = event.progress) // TODO integrate "elementCreated"
}
}
is ActionListenerEvent.Finished -> {
runningActions.remove(event.actionId)
}
}
emit(runningActions.values)
}
}
uj5u.com熱心網友回復:
interface ActionListener {
fun actionStarted(actionId: Int)
fun actionProgress(actionId: Int, progress: Float, elementCreated: ExampleElement)
fun actionEnd(actionId: Int)
}
class MainProductor(val actionListener: ActionListener) {
fun start() {
//start some heavy works that start to call actionListener
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/448690.html
下一篇:Flutter如何使用彩色圖示
