![](/img/trans.png)
[英]How can i send data from Activity to Fragment using LiveData and ViewModel class
[英]How can I get data from ViewModel to Activity or Fragment in clean and simple way?
我有一个问题......有时,我需要直接从 ViewModel 获取数据。 例如,假设 ViewModel 中有一个isChecked()
方法。 我想在 if 条件下使用它。
if(viewModel.isChecked()){
// TODO:
}
所以,我现在正在做的是:
fun isChecked(): Boolean = runBlocking {
val result = dbRepo.getData()
val response = apiRepo.check(result)
return response.isSuccessful
}
它使用 runBlocking。 因此,它在 MainThread 上运行。 我认为这不是一个好方法,因为它可以冻结屏幕。 但是是的,如果条件需要运行,它需要等待它从数据库和网络获取数据。
我能想到的另一种方法是使用 LiveData。 但是,我不能在这种情况下使用它。 所以,我需要在观察者块中移动条件。 但有时,这不能完成,因为条件之前可能有一些东西。 它看起来并不直接,而是在这里和那里编写代码并最终获得该数据。
那么,还有比这更简单的方法吗?
使用lifecyclescope.launch(Dispatcher.IO) 而不是runblocking
如果您有类似的异步操作,最好的选择是重新考虑如何完全使用数据。 不要尝试返回它,而是使用 LiveData 或回调来异步处理响应,而不会导致 UI 挂起或变得滞后。
回调获取 state
如果没有关于如何使用isChecked()
的更多详细信息,很难确定最适合您的解决方案是什么,但是一种可行的模式是使用回调来处理您以前放入 if 语句中的内容,就像这样(在视图模型中):
fun getCheckedState(callback: (Boolean)->Unit) {
viewModelScope.launch {
// do long-running task to get checked state,
// using an appropriate dispatcher if needed
val result = dbRepo.getData()
val response = apiRepo.check(result)
// pass "response.isSuccessful" to the callback, to be
// used as "isChecked" below
callback(response.isSuccessful)
}
}
您可以像这样从活动或片段中调用它:
viewModel.getCheckedState { isChecked ->
if( isChecked ) {
// do something
}
else {
// do something else
}
}
// CAUTION: Do NOT try to use variables you set inside
// the callback out here!
请注意- 您传递给getCheckedState
的回调中的代码不会立即运行。 不要尝试在回调 scope 之外使用你在里面设置的东西,否则你会陷入这个常见问题
更简单的回调
或者,如果你只想在isChecked
为真时运行一些代码,你可以像这样简化回调
fun runIfChecked(callback: ()->Unit) {
viewModelScope.launch {
// do long-running task to get checked state,
// using an appropriate dispatcher if needed
val result = dbRepo.getData()
val response = apiRepo.check(result)
// pass "response.isSuccessful" to the callback, to be
// used as "isChecked" below
if( response.isSuccessful ) {
callback()
}
}
}
并调用它
viewModel.runIfChecked {
// do something
}
// Again, don't try to use things from the callback out here!
在您的 ViewModel class 上尝试以下代码:
suspend fun isChecked(): Boolean {
val response: Response? = null
val job = viewModelScope.launch(Dispatchers.IO) {
response = dbRepo.getData()
}
job.join()
return response.isSuccessful
}
从活动:
viewModel.viewModelScope.launch(Dispatchers.IO) {
if (viewModel.isChecked()) {
// Do your staff
}
}
希望它工作文件。 如果没有让我评论
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.