Android Compose返回导航后如何清除ViewModel中的数据?
解决方案:再次进入ScreenB时清空ViewModelB的amount值
针对你遇到的问题,这里提供几个实用的实现方案,根据你的业务需求选择即可:
方案1:利用LaunchedEffect监听页面进入事件
在ScreenB中通过LaunchedEffect监听页面加载,每次进入时主动清空amount值,无需修改ViewModel的生命周期作用域:
ScreenB代码:
@Composable fun ScreenB(viewModel: ViewModelB = viewModel()) { // 每次进入ScreenB时触发清空逻辑 LaunchedEffect(Unit) { viewModel.clearAmount() } // 界面绑定逻辑 TextField( value = viewModel.amountValue.value, onValueChange = viewModel::updateAmount, label = { Text("Amount") } ) }
ViewModelB补充清空方法:
class ViewModelB : ViewModel() { val amountValue = mutableStateOf("") fun updateAmount(newValue: String) { amountValue.value = newValue } fun clearAmount() { amountValue.value = "" } }
方案2:让ViewModelB与ScreenB生命周期绑定
如果希望ViewModelB完全随ScreenB的进入/销毁而创建/回收(返回A时自动销毁ViewModelB),可以借助Compose Navigation的BackStackEntry作为ViewModel的作用域:
ScreenB代码(普通ViewModel):
@Composable fun ScreenB(navController: NavController) { // 获取当前页面的BackStackEntry作为ViewModel的宿主 val backStackEntry = checkNotNull(navController.currentBackStackEntry) { "ScreenB必须存在于导航栈中" } val viewModel: ViewModelB = viewModel(viewModelStoreOwner = backStackEntry) // 界面绑定逻辑... }
若使用Hilt注入:
@Composable fun ScreenB(navController: NavController) { val backStackEntry = navController.currentBackStackEntry!! val viewModel: ViewModelB = hiltViewModel(backStackEntry) // 界面绑定逻辑... }
此方案下,从B返回A时,B对应的BackStackEntry会被移除,ViewModelB会自动销毁,再次进入B时会创建全新实例,amount值自然为空。
方案3:跳转前主动清空(简易场景)
如果跳转逻辑简单,也可以在ScreenA跳转到B之前,直接调用ViewModel的清空方法:
@Composable fun ScreenA(navController: NavController, viewModelB: ViewModelB) { Button(onClick = { viewModelB.clearAmount() navController.navigate("screenB") }) { Text("进入页面B") } }
内容的提问来源于stack exchange,提问作者Sandeep Tak
相关产品推荐
相关产品推荐

