【问题标题】:How to observe Emited LiveData with MVVM如何使用 MVVM 观察 Emited LiveData
【发布时间】:2020-02-10 11:56:30
【问题描述】:

我很难理解如何处理发出的 liveData。我在这里写了四个不同的 liveData 示例,

class MainViewModel : ViewModel() {
    val viewModelValue = MyRepo.liveValue
    fun viewModelGetNextValue(){
        MyRepo.getNextValue()
    }

    val viewModelSquareValue = MyRepo.squareLiveValue
    fun viewModelGetSquareValue(x:Int){
        MyRepo.getSquareValue(x)
    }

    val viewModelEmitValue = MyRepo.emitLiveValue

    lateinit var viewModelEmitFunctionValue:LiveData<String>
    fun viewModelEmitLiveFunction(x:Int){
        viewModelEmitFunctionValue = MyRepo.emitLiveFunction(x)
    }
}

object MyRepo{
    var value = 1

    val liveValue = MutableLiveData<Int>()
    fun getNextValue(){
        liveValue.postValue(++value)
    }

    val squareLiveValue = MutableLiveData<Int>()
    fun getSquareValue(x:Int){
        squareLiveValue.postValue(x*x)
    }

    val emitLiveValue = liveData {
        emit("First Emit")
        delay(2000)
        emit("second value")
    }

    fun emitLiveFunction(x:Int) = liveData {
        emit("value: $x")
        delay(2000)
        emit("square: ${x*x}")
    }
}

而片段代码的一部分是,

        viewModel.viewModelValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, "$it", Toast.LENGTH_SHORT).show()
        })
        viewModel.viewModelSquareValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, "$it", Toast.LENGTH_SHORT).show()
            viewModel.viewModelSquareValue.removeObservers(viewLifecycleOwner)
        })
        viewModel.viewModelEmitValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, it, Toast.LENGTH_SHORT).show()
        })

        button1.setOnClickListener { viewModel.viewModelGetNextValue() }
        button2.setOnClickListener { viewModel.viewModelGetSquareValue(++x) }
        button3.setOnClickListener {
            viewModel.viewModelEmitLiveFunction(++x)
            viewModel.viewModelEmitFunctionValue.observe(viewLifecycleOwner, Observer {
                Toast.makeText(activity, it, Toast.LENGTH_SHORT).show()
            })
        }

LiveData 的前两个示例(viewModelValueviewModelSquareValue)很容易观察。并且可以使用按钮的点击监听器调用。我使用过emit 的第三个livedata viewModelEmitValue 会自动显示该值。

如果我想要按钮后的这些值,我该怎么办 点击?我只需要在点击中编写观察者代码吗 听众?

最后一个 liveData viewModelEmitFunctionValue 正在工作。但是是不是 如果我想在单击 a 后获取该值,唯一的方法(使用 lateinit var) 按钮?

【问题讨论】:

    标签: android android-livedata kotlin-coroutines android-viewmodel


    【解决方案1】:

    最后一个 liveData viewModelEmitFunctionValue 正在工作。但是,如果我想在单击按钮后获取值,这是唯一的方法(使用 lateinit var)吗?

    通过这种方式,您为每个按钮单击创建观察者,每隔一次单击添加一个额外的 Toast。好消息是,您每次点击都会创建 LiveData 实例,以便清理以前的观察者。但这有点混乱。

    val emitLiveValue = liveData { 不是一种懒惰的方式来声明 LiveData,所以一旦你的 Repo 被初始化,它就会开始在 liveData{} 中执行代码

    fun emitLiveFunction(x:Int) = liveData { 的情况下,您仅在调用函数时创建 LiveData,这就是它运行良好的原因。

    我的建议是将x 值存储在实时数据中,并在每次更改时计算emitLiveFunction。你可以使用Transformations.switchMap实现它

    class MainViewModel : ViewModel() {
    ...
      private val x = MutableLiveData<Int>()
      val functionResult = x.switchMap { MyRepo.emitLiveFunction(it) }
    
      fun viewModelEmitLiveFunction(x:Int) { 
          this.x.postValue(x)
      }
    }
    

    现在您可以在创建活动后立即将观察者添加到functionResult,并在按钮 3 上调用 viewModelEmitLiveFunction(x),您将使用新值 x 启动 repo 函数执行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      相关资源
      最近更新 更多