我对 Android Flow 和 JetPack compose 很陌生,
我试图在更改可变状态时更新我的 UI,但这不是调用我们的可组合项,这是我的代码
@Composable
fun Grid() {
val mainViewModel by viewModels<DashBoardViewModel>()
mainViewModel.getData()
when (val result = mainViewModel.mutableState.value) {
is Resource.Success -> {
LazyVerticalGrid(
cells = GridCells.Adaptive(100.dp)
) {
items(result.device.items.first().devices.count()) {
EachItem(it)
}
}
}
is Resource.Error -> { Text(text = result.message) }
Resource.Loading -> { CircularProgressIndicator() }
Resource.Empty -> {}
else -> { CircularProgressIndicator() }
}
}
View 模型:
@HiltViewModel
class DashBoardViewModel @Inject constructor(
private val dashBoardRepository: DashBoardRepository
) : ViewModel() {
val mutableState = MutableLiveData<Resource>()
fun getData() = viewModelScope.launch {
flow {
emit(Resource.Loading)
try {
val mResponse = dashBoardRepository.getDevice()
emit(Resource.Success(mResponse))
} catch (e: Exception) {
e.printStackTrace()
emit(Resource.Error("Error"))
}
}.flowOn(Dispatchers.IO).collect {
mutableState.value = it
}
}
}
最佳答案
您的代码中有两个问题:
mainViewModel.mutableState.value
仅从可变状态获取当前值。当该值更改时,您的可组合项不会收到通知,因此它无法反射(reflect)更改。如果您想在 View 模型中使用LiveData
,则必须使用observeAsState()
extension function它将LivaData
转换为可以通过可组合函数自动观察的State
。另一种选择是直接在 View 模型中使用(Mutable)State
。请参阅this说明。- 每次
Grid()
函数重组时,都会调用您的mainViewModel.getData()
函数,这将在每次mainViewModel.mutableState
时调用code> 更改(一旦您正确观察)。你绝对不希望这样。更好的解决方案是从 viewModel 的init
block 中调用getData()
,或者,如果您确实需要从可组合函数中调用它,请使用 LaunchedEffect .
顺便说一句,您创建流然后将其收集到 LiveData 中的方式确实很奇怪而且没有必要。你可以这样做:
fun getData() = viewModelScope.launch {
mutableState.value = Resource.Loading
try {
val mResponse = dashBoardRepository.getDevice()
mutableState.value = Resource.Success(mResponse)
} catch (e: Exception) {
e.printStackTrace()
mutableState.value = Resource.Error("Error")
}
}
关于android-jetpack-compose - Ui 未从 viewmodel kotlin flow 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71379141/