[英]How can I generate a String in a function in a viewmodel and return to a fragment in Kotlin?
I want to generate a String in a function in my viewmodel and send it to the fragment associated to this viewmodel as a LiveData, how can I do it?我想在我的视图模型中的 function 中生成一个字符串,并将其作为 LiveData 发送到与此视图模型关联的片段,我该怎么做?
For example, my viewmodel:例如,我的视图模型:
class MaskViewModel : ViewModel() {
var mask: MutableLiveData<String> = newQuestion()
fun newQuestion(): MutableLiveData<String>{
mask.value="255"
return mask
}
}
And the observer in my fragment:我片段中的观察者:
maskviewModel.mask.observe(viewLifecycleOwner){ result ->
binding.textView3.text=result
}
You appear to be all set up to observe any changes to your mask
variable within your fragment.您似乎已准备好观察片段中
mask
变量的任何变化。 To set a new String to it, simply call mask.postValue(myString)
within your function. This will trigger your observer, which will receive the new value of mask
as result
.要为其设置一个新字符串,只需在您的 function 中调用
mask.postValue(myString)
即可。这将触发您的观察者,它将收到mask
的新值作为result
。
Additionally, you are not assigning an instance of MutableLiveData
to mask
.此外,您没有将
MutableLiveData
的实例分配给mask
。 Your newQuestion()
never creates an instance of MutableLiveData
, but rather tries to access it while it is still null.您的
newQuestion()
永远不会创建MutableLiveData
的实例,而是在它仍然是 null 时尝试访问它。
Instantiate it this way: val mask: MutableLiveData<String> = MutableLiveData()
.以这种方式实例化它:
val mask: MutableLiveData<String> = MutableLiveData()
。 Then you can call .postValue()
on it.然后你可以在上面调用
.postValue()
。 I've changed it to val
because you can keep it as the same reference but still change the value within it.我已将其更改为
val
,因为您可以将其保留为相同的引用,但仍会更改其中的值。 Keep it as var
only if you wish to reassign it to a new MutableLiveData
at some point, which is unlikely.仅当您希望在某个时候将其重新分配给新的
MutableLiveData
时,才将其保留为var
,这不太可能。
Your function should not return a LiveData or replace the existing LiveData.您的 function 不应返回 LiveData 或替换现有的 LiveData。 You should only have a single LiveData instance so when the Fragment observes it, it will get all future changes.
您应该只有一个 LiveData 实例,这样当 Fragment 观察到它时,它将获得所有未来的更改。
class MaskViewModel : ViewModel() {
val mask = MutableLiveData<String>()
fun newQuestion() {
mask.value="255"
}
}
But it is better encapsulation not to expose your LiveData as being mutable outside the class, so this is better:但最好封装不要将 LiveData 公开为在 class 之外可变,所以这样更好:
class MaskViewModel : ViewModel() {
private val _mask = MutableLiveData<String>()
val mask: LiveData<String> get() = _mask
fun newQuestion() {
_mask.value="255"
}
}
As @Tenfour04 mentions in his answer, your function should not return LiveData
.正如@Tenfour04 在他的回答中提到的那样,您的 function 不应返回
LiveData
。
instead of returning the string from your viewModel
, you could return it's id, and call the string from fragment.您可以返回它的 ID,而不是从您的
viewModel
返回字符串,然后从片段中调用该字符串。
in the ViewModel
在
ViewModel
中
private val _mask = MutableLiveData<Int>()
val mask: LiveData<Int> get() = _mask
fun newQuestion() {
_mask.value = R.string.mask_value
}
in the Fragment
在
Fragment
中
maskviewModel.mask.observe(viewLifecycleOwner){ id ->
binding.textView3.text = requireContext().getString(id)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.