我的 Android 应用程序中有一个 ViewModel,它有一些逻辑,视图需要 adjusted/perform 不同的东西,具体取决于该逻辑的结果。起初我尝试专门与观察者一起做,并对 viewmodel 中的数据状态做出反应,但这太复杂了。
然后我使用 SingleLiveEvent 类找到了命令的概念,我发现它很好,因为它在使用 Xamarin 和 microsoft 的 mvvvm 时提醒我相同的模式。使用 xamarin 的(少数)好事之一;)
好吧,我的问题是当我有多个命令需要发送到视图时,视图只接收一个命令。有时是最后一个,有时是第一个。例如,有几个命令命令视图执行复杂的操作:
sealed class CustomCommands{
class CustomCommand1 : CustomCommands()
class CustomCommand2() : CustomCommands()
class CustomCommand3() : CustomCommands()
class CustomCommand4() : CustomCommands()
class CustomCommand5() : CustomCommands()
}
然后在我的 viewModel 中,我有命令 SingleLiveEvent 对象:
class CustomViewModel...{
val commands: SingleLiveEvent<CustomCommands> = SingleLiveEvent()
private fun doComplicatedThingsOnTheUI() {
GlobalScope.launch(Dispatchers.IO) {
if (someConditionsInvolvingRestRequestsAndDatabaseOperations()){
commands.postValue(CustomCommands.CustomCommand1())
commands.postValue(CustomCommands.CustomCommand2())
} else {
commands.postValue(CustomCommands.CustomCommand3())
commands.postValue(CustomCommands.CustomCommand4())
}
commands.postValue(CustomCommands.CustomCommand5())
}
}
}
在 Activity/Fragment 中,我有命令的观察者,应该对每个命令作出反应并完成工作:
class MainActivity...{
viewModel.commands.observe(this, Observer { command ->
Rlog.d("SingleLiveEvent", "Observer received event: " + command.javaClass.simpleName)
when (command) {
Command1->doSomething1()
Command2->doSomething2()
}
}
好吧,问题是视图通常只接收最后一个命令(Command5)。但行为取决于 Android SDK 的 api 级别。通过 api 16,视图接收最后一个命令。通过 Api 28,视图通常接收第一个和最后一个命令(例如,Command1 和 Command5,但不接收 Command2)。
也许我理解 SingleLiveEvent 类的功能错误,或整个 Command 事情错误,但我需要一种方法来允许 viewmodel 根据许多对象和变量的状态对视图进行排序。上面的代码只是一个样本,现实比这更复杂。
我不想在 viewmodel 和视图之间使用回调,因为我读到的地方破坏了整个 MVVM 模式。
也许有人对我有建议。欢迎任何帮助。
先感谢您。
1 回答
我想我找到了一个解决方法,似乎有效(我已经测试了几个小时)。
问题是我正在使用“command.postValue(XXX)”,因为那段代码在一个 couroutine 中运行,也就是说,在其他线程中运行。因为我不能直接使用 command.value。
但事实是使用 command.value=Command1(),它的工作原理。我的意思是,视图接收发送的所有命令,并且非常重要,其顺序与发送时相同。因此,我写了一个小功能,将命令发送到 UI 切换线程。
我不确定这是否正确,我是 Kotlin 协同程序的新手,我不得不承认我还不太了解它们:
然后我发送命令
这似乎有效。但是,“post”方法可以以类似的方式工作,但事实并非如此。
问候。