Kotlin StateFlow新值已发送但未被收集问题排查
问题排查与解决
错误1:ViewModel变量名笔误
看你的LocationViewModel中updateShippingLocation方法:
fun updateShippingLocation(location: String?) { sharedPreferences.edit() .putString(PREFS_SHIPPING_LOCATION_KEY, location) .apply() _shippingLocationWilaya.value = location // 变量名错误! }
你更新的是_shippingLocationWilaya,但对外暴露的shippingLocation StateFlow是基于_shippingLocation的,这直接导致更新操作没有触发数据流发射,Fragment自然收不到新值。
修正:将变量名改为正确的_shippingLocation:
fun updateShippingLocation(location: String?) { sharedPreferences.edit() .putString(PREFS_SHIPPING_LOCATION_KEY, location) .apply() _shippingLocation.value = location }
错误2:BottomSheet获取的是全新ViewModel实例
你的EditLocationFragment中用val viewModel: LocationViewModel by viewModels()获取ViewModel,默认情况下这个ViewModel的生命周期绑定到BottomSheet自身,和原Fragment的ViewModel不是同一个实例。你在BottomSheet里调用updateShippingLocation,更新的是新实例的StateFlow,原Fragment监听的是另一个实例的数据流,完全收不到通知。
修正:让BottomSheet共享原Fragment的ViewModel,指定ViewModelStoreOwner为父Fragment或Activity:
// 方式1:共享父Fragment的ViewModel val viewModel: LocationViewModel by viewModels({ requireParentFragment() }) // 方式2:如果是和Activity共享,用activityViewModels() val viewModel: LocationViewModel by activityViewModels()
额外优化建议
getShippingLocation方法里不需要用viewModelScope.launch,读取SharedPreferences是同步操作,直接赋值即可:
private fun getShippingLocation() { val location = sharedPreferences.getString(PREFS_SHIPPING_LOCATION_KEY, null) _shippingLocation.value = location ?: "" }
内容的提问来源于stack exchange,提问作者Jamal N
相关产品推荐
相关产品推荐

