Navigation组件中Fragment重建为何ViewModel未被重新创建?
问题原因
在Navigation组件2.5.0及以上版本中,当Fragment作为NavHostFragment的子目的地时,默认情况下,ViewModelProvider(this)(或by viewModels())会将NavHostFragment作为ViewModel的实际所有者,而非当前Fragment实例。这是Navigation组件引入的新行为,目的是让子Fragment共享NavHostFragment的ViewModelStore,实现跨目的地的ViewModel复用。
因此,即使切换底部导航导致DashboardFragment实例被销毁重建,ViewModel的生命周期仍绑定在NavHostFragment上(NavHostFragment的生命周期与Activity一致,不会随子Fragment销毁而结束),所以ViewModel不会重新初始化。
解决方案
如果你希望ViewModel的生命周期与Fragment实例绑定,在Fragment销毁时也随之销毁,需要明确指定ViewModelStoreOwner为当前Fragment:
- 使用
viewModels()扩展函数时,显式传入ownerProducer参数:
private val viewModel: DashboardViewModel by viewModels(ownerProducer = { this })
- 或者直接使用ViewModelProvider时,明确传入当前Fragment作为ViewModelStoreOwner:
private val viewModel: DashboardViewModel by lazy { ViewModelProvider(this).get(DashboardViewModel::class.java) }
这样就能确保ViewModel的生命周期与当前Fragment实例绑定,Fragment销毁时ViewModel也会被清理。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

