【问题标题】:Kotlin: How to change values of MutableLiveData in ViewModel without using getters and settersKotlin:如何在不使用 getter 和 setter 的情况下更改 ViewModel 中 MutableLiveData 的值
【发布时间】:2020-06-22 13:45:41
【问题描述】:

这是我的视图模型:

class MyProfileEditSharedViewModel : ViewModel() {
    val question = MutableLiveData<String>()
    val answer = MutableLiveData<String>()

    fun setQuestion (q: String) {
        question.value = q
    }

    fun setAnswer (a: String) {
        answer.value = a
    }
}

我使用 setQuestion 和 setAnswer 设置数据,如下所示:

viewModel.setQuestion(currentUserInList.question)
viewModel.setAnswer(currentUserInList.answer)

我尝试从 ViewModel 中获取问题和答案,如下所示:

val qnaQuestionData = communicationViewModel.question as String
val qnaAnswerData = communicationViewModel.answer as String

编译器说我不能将 MutableLiveData 转换为字符串。 我应该像我的二传手一样制作一个单独的吸气剂吗?听说kotlin不需要使用getter和setter,有没有办法在我的viewmodel中编辑val question和val answer而不使用getter和setter?

谢谢!!

【问题讨论】:

  • 您应该观察LiveData 以获取其中更改的通知,而不是手动提取数据。请参阅文档:developer.android.com/topic/libraries/architecture/…
  • 您会使用 val qnaQuestionData = communicationViewModel.question.value ?: someDefault 之类的东西,但通常您不希望同步检索 LiveData 的值,因为这违背了使用 LiveData 的目的。

标签: android kotlin viewmodel


【解决方案1】:

您不能将其转换为String,因为对象的类型是MutableLiveData,但您可以使用.value 属性访问该值

val qnaQuestionData = communicationViewModel.question.value
val qnaAnswerData = communicationViewModel.answer.value

在这种情况下,可能会遇到关于MutableLiveData 初始化的错误。

另一种方法是观察 LiveData 的变化:

communicationViewModel.question.observe(this, Observer{ data->
 ...
})

或者如果您没有访问任何生命周期所有者

communicationViewModel.question.observeForever(Observer{ data->
 ...
})

但请记得通过removeObserver方法移除观察者

  • 设置值最好直接使用属性或绑定方式
communicationViewModel.question.postValue("some new value")

或者

communicationViewModel.question.value = "some new value"
  • 关于 MutableLiveData 属性的建议
val question: MutableLiveData<String> by lazy { MutableLiveData<String>() }
val answer: MutableLiveData<String> by lazy { MutableLiveData<String>() }

https://developer.android.com/reference/android/arch/lifecycle/LiveData

【讨论】:

    【解决方案2】:

    在您的 ViewModel 中创建某种 getter 方法

    fun getQuestion(): LiveData<String> {
            return question //this works because MutableLiveData is a subclass of LiveData
    }
    

    然后,您可以在您关心的任何类中观察该值。即:

    communicationsViewModel.getQuestion().observe(this, Observer {
           //do something with the value which is 'it'. Maybe qnaQuestionData = it
    }
    

    请注意,如果您尝试从片段或其他内容中观察值,则必须将参数 this 更改为 viewLifecycleOwner

    【讨论】:

    • 在不使用 getter 和 setter 的情况下有没有办法做到这一点?
    • MutableLiveData 属性设为私有,并将另一个属性设为LiveData。例如,private val _question = MutableLiveData&lt;String&gt;(); val question: LiveData&lt;String&gt; = _question
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2018-06-10
    相关资源
    最近更新 更多