Oni*_*vas 0 android viewmodel android-jetpack-compose
我正在编写一个简单的应用程序,以便学习,该应用程序有两个viewModels,ItemListViewModel显示项目列表并ItemCreateViewModel让您创建项目,项目存储在 Room 中。
我的问题是,当我打开应用程序时,会显示列表,但在我打开详细信息并创建新项目后,返回第一个 ( ItemListViewModel) 列表不会更新。
@HiltViewModel
class ItemListViewModel
@Inject
constructor(private val itemRepository: ItemRepository) : ViewModel() {
var uiState by mutableStateOf(value = ItemListState(state = State.LOADING))
private set
init {
viewModelScope.launch(Dispatchers.IO) {
itemRepository.fetchItems()
.distinctUntilChanged()
.collect { items ->
uiState = uiState.copy(
state = State.IDLE,
items = if (items.isNullOrEmpty()) emptyList() else items
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里是撰写视图
@Composable
fun ItemList(
viewModel: ItemListViewModel,
navController: NavController
) {
val items = viewModel.uiState.items
ShowItems(items) // <--- this is not called
}
Run Code Online (Sandbox Code Playgroud)
这是存储库的乐趣
fun fetchItems(): Flow<List<ItemEntity>>
Run Code Online (Sandbox Code Playgroud)
如果我终止该应用程序并重新启动它,我可以看到新创建的项目。
您的列表不会刷新,因为您的协程在导航到CreateMedicineScreen屏幕时被取消。当您返回MedicineList屏幕时,init不会调用(因为它是同一个 ViewModel 实例)。您可以将刷新公开为 ViewModel 中的公共方法(正如您在代码中开始的那样),并使用副作用从可组合项中调用它。
@Composable
fun MedicineList(
viewModel: MedicineListViewModel,
navController: NavController
) {
LaunchedEffect(Unit) {
viewModel.fetchMedicines()
}
val medicines = viewModel.uiState.medicines
ShowMedicines(medicines) {
navController.navigate(NEW_MEDICINE_ROUTE)
}
}
Run Code Online (Sandbox Code Playgroud)
当您弹回屏幕时,MedicineList将重新组合并执行一次 fetch 方法。
作为奖励,我注意到您在从CreateMedicineScreen屏幕保存时返回导航时遇到问题。这是因为您正在尝试从可组合项进行导航。文档中也有具体说明
您应该仅将 navigator() 作为回调的一部分调用,而不是作为可组合项本身的一部分,以避免在每次重组时调用 navigator()。
您也可以在这里使用副作用:
LaunchedEffect(key1 = Unit) {
navController.popBackStack()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4118 次 |
| 最近记录: |