android - 如何使用 SingleLiveEvent 类将多个命令从 MVVM 发送到 View

标签 android mvvm command

我的 Android 应用程序中有一个 ViewModel,它具有一些逻辑,并且 View 需要根据该逻辑的结果进行调整/执行不同的操作。起初,我尝试只与观察者一起做,并对 View 模型中的数据状态使用react,但它太复杂了。

然后我找到了使用 SingleLiveEvent 类的命令的概念,我发现它很好,因为它让我想起了使用 Xamarin 和微软的 mvvvm 时的相同模式。与 xamarin 一起工作的(少数)好处之一是 ;)

我的问题是,当我有多个命令需要发送到 View 时, View 只接收一个命令。有时是最后一个,有时是第一个。例如,命令 View 执行复杂操作的几个命令:

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 中,我有命令的观察者,它应该对每个命令使用react并完成工作:

class MainActivity...{

viewModel.commands.observe(this, Observer { command ->
            Rlog.d("SingleLiveEvent", "Observer received event: " + command.javaClass.simpleName)
            when (command) {
Command1->doSomething1()
Command2->doSomething2()
}

}

嗯,问题是 View 通常只接收最后一个命令 (Command5)。但行为取决于 Android SDK 的 api 级别。通过 api 16, View 接收到最后一条命令。通过 Api 28, View 正常接收第一个和最后一个命令(例如,Command1 和 Command5,但不是 Command2)。

也许我对 SingleLiveEvent 类的功能的理解有误,或者整个 Command 的理解有误,但我需要一种方法来允许 View 模型根据许多对象和变量的状态命令 View 执行某些操作。上面的代码只是一个示例,实际情况要复杂得多。

我不想在 View 模型和 View 之间使用回调,因为我在某处读到它破坏了整个 MVVM 模式。

也许有人对我有建议。欢迎任何帮助。

提前谢谢你。

最佳答案

我想我找到了一个似乎可行的解决方法(我只测试了几个小时)。

问题是我使用的是“command.postValue(XXX)”,因为那段代码在协程中运行,也就是说,在其他线程中运行。因此我不能直接使用 command.value。

但事实是,使用 command.value=Command1() 是可行的。我的意思是, View 接收所有发送的命令,这也非常重要,与发送的顺序相同。因此,我编写了一个小函数来将命令发送到切换线程的 UI。

我不确定这是否正确,我是 Kotlin 协程的新手,我不得不承认我还不太了解它们:

    private suspend fun sendCommandToView(vararg icommands: CustomCommands) = withContext(Dispatchers.Main) {
    icommands.forEach {
        commands.value = it
    }
}

然后我发送命令

sendCommandToView(CustomCommand1(),CustomCommand2(),CustomCommand5())

这似乎可行。原以为“post”方法会以类似的方式工作,但事实并非如此。

问候。

关于android - 如何使用 SingleLiveEvent 类将多个命令从 MVVM 发送到 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53739188/

相关文章:

java - 使用 java.nio 时抛出 IllegalArgumentException

html - UI 和 Local Storage 绑定(bind)在一起

c# - 在不阻塞 UI 的情况下在 ViewModel 中加载大量数据

wpf - 如何将 WPF 命令绑定(bind)到 MouseEnter 事件?

Flutter 未加载设备并显示 'Waiting for another flutter command to release the startup lock...'

android - 如何解决 Late-enabling CheckJNI?

android - 如何在 Android 中创建自定义 PopupMenu

android - ionic : hide Android App Launcher?

c# - 从sql数据库检索图像(字节数组)并显示图像

java - 一般返回类型 - Java