如何使用MVVM观察发射的LiveData

问题描述 投票:0回答:1

我正在努力了解如何处理发出的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)很容易观察到。并可以通过按钮的点击监听器调用。我使用过viewModelEmitValue的第三个实时数据emit自动显示该值。

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

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

android android-livedata kotlin-coroutines android-viewmodel
1个回答
0
投票

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

这样,您将为每个按钮单击创建观察者,每单击一次将添加一个Toast。好消息是您还需要每次单击都创建LiveData实例,以便清理先前的观察者。但这有点杂乱。

val emitLiveValue = liveData {并不是声明LiveData的惰性方法,因此一旦您对Repo进行初始化,它就会开始在liveData{}中执行代码。

fun emitLiveFunction(x:Int) = liveData {的情况下,您仅在调用函数时才创建LiveData,因此这才可以正常工作。

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

实现
val x = MutableLiveData<Int>()
val functionResult = x.switchMap { emitLiveFunction(it) }

fun viewModelEmitLiveFunction(x:Int) { 
    this.x.postValue(x)
}

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

© www.soinside.com 2019 - 2024. All rights reserved.