返回应用程序后触发 MutableStateFlow
MutableStateFlow is triggered after returning to the app
在我的 MainActivity
我有 BottomNavigation
。我的 activity 连接到 MainViewModel
。当应用程序启动时,我从 firebase 获取数据。在数据下载完成之前,应用程序显示 ProgressBar
并且 BottomNavigation
隐藏(view.visibility = GONE)。下载数据后,我会隐藏 ProgressBar
并显示 BottomNavigation
以及应用程序的内容。效果很好。
在应用程序的另一部分,用户可以打开图库并选择照片。问题是当 activity with photo to choose 已关闭时,MutableStateFlow
被触发并再次显示 bottomNavigation
但它应该隐藏在应用程序的特定部分(片段)中。
为什么我的 MutableStateFlow 会被触发,尽管当用户从画廊返回时我没有向它发送任何东西 activity?
MainActivity (onStart):
private val mainSharedViewModel by viewModel<MainSharedViewModel>()
override fun onStart() {
super.onStart()
lifecycle.addObserver(mainSharedViewModel)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
val navHostFragment: FragmentContainerView = findViewById(R.id.bottomNavHostFragment)
bottomNavController = navHostFragment.findNavController()
bottomNavigationView.apply {
visibility = View.GONE
setupWithNavController(navHostFragment.findNavController())
}
//the fragment from wchich I open GalleryActivity is hide (else ->)
navHostFragment.findNavController().addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.mainFragment,
R.id.profileFragment,
R.id.homeFragment -> bottomNavigationView.visibility = View.VISIBLE
else -> bottomNavigationView.visibility = View.GONE
}
}
mainSharedViewModel.viewModelScope.launch {
mainSharedViewModel.state.userDataLoadingState.collect {
if (it == UserDataLoading.LOADED) {
bottomNavigationView.visibility = View.VISIBLE
} else {
bottomNavigationView.visibility = View.GONE
}
}
}
}
视图模型:
class MainSharedViewState {
val userDataLoadingState = MutableStateFlow(UserDataLoading.LOADING) }
enum class UserDataLoading {
LOADING, UNKNOWN_ERROR, NO_CONNECTION_ERROR, LOADED }
当你从画廊回来时,stateflow 值仍然设置为 Loaded,因为 Viewmodel 还没有被清除(并且 activity 被设置为 Stopped,没有被销毁。它仍然在back stack.) 这就是为什么当你回来时 bottomNavigationView 是可见的。
虽然您的 architecture/solution 不是我的做法,但在您的情况下,我想您可以在调用 activity 的 onStop 时更改 MutableStateFlow 的值。或者使用 MutableSharedFlow 而不是 replayCount 为 0,这样就不会收集任何值(尽管如此,如果 bottomNavigationView 在 XML 中默认可见,则它仍将设置为可见。)
已解决:
我创造了
val userDataLoadingState = MutableSharedFlow<UserDataLoading>(replay = 0)
创建 ViewModel 时我设置了
state.userDataLoadingState.emit(UserDataLoading.LOADING)
我在 Activity
中收集数据
lifecycleScope.launch {
mainSharedViewModel.state.userDataLoadingState.collect {
if (it == UserDataLoading.LOADED) {
bottomNavigationView.visibility = View.VISIBLE
} else {
bottomNavigationView.visibility = View.GONE
}
}
}
现在效果很好。之前不知道为什么不行
在我的 MainActivity
我有 BottomNavigation
。我的 activity 连接到 MainViewModel
。当应用程序启动时,我从 firebase 获取数据。在数据下载完成之前,应用程序显示 ProgressBar
并且 BottomNavigation
隐藏(view.visibility = GONE)。下载数据后,我会隐藏 ProgressBar
并显示 BottomNavigation
以及应用程序的内容。效果很好。
在应用程序的另一部分,用户可以打开图库并选择照片。问题是当 activity with photo to choose 已关闭时,MutableStateFlow
被触发并再次显示 bottomNavigation
但它应该隐藏在应用程序的特定部分(片段)中。
为什么我的 MutableStateFlow 会被触发,尽管当用户从画廊返回时我没有向它发送任何东西 activity?
MainActivity (onStart):
private val mainSharedViewModel by viewModel<MainSharedViewModel>()
override fun onStart() {
super.onStart()
lifecycle.addObserver(mainSharedViewModel)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
val navHostFragment: FragmentContainerView = findViewById(R.id.bottomNavHostFragment)
bottomNavController = navHostFragment.findNavController()
bottomNavigationView.apply {
visibility = View.GONE
setupWithNavController(navHostFragment.findNavController())
}
//the fragment from wchich I open GalleryActivity is hide (else ->)
navHostFragment.findNavController().addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.mainFragment,
R.id.profileFragment,
R.id.homeFragment -> bottomNavigationView.visibility = View.VISIBLE
else -> bottomNavigationView.visibility = View.GONE
}
}
mainSharedViewModel.viewModelScope.launch {
mainSharedViewModel.state.userDataLoadingState.collect {
if (it == UserDataLoading.LOADED) {
bottomNavigationView.visibility = View.VISIBLE
} else {
bottomNavigationView.visibility = View.GONE
}
}
}
}
视图模型:
class MainSharedViewState {
val userDataLoadingState = MutableStateFlow(UserDataLoading.LOADING) }
enum class UserDataLoading {
LOADING, UNKNOWN_ERROR, NO_CONNECTION_ERROR, LOADED }
当你从画廊回来时,stateflow 值仍然设置为 Loaded,因为 Viewmodel 还没有被清除(并且 activity 被设置为 Stopped,没有被销毁。它仍然在back stack.) 这就是为什么当你回来时 bottomNavigationView 是可见的。
虽然您的 architecture/solution 不是我的做法,但在您的情况下,我想您可以在调用 activity 的 onStop 时更改 MutableStateFlow 的值。或者使用 MutableSharedFlow 而不是 replayCount 为 0,这样就不会收集任何值(尽管如此,如果 bottomNavigationView 在 XML 中默认可见,则它仍将设置为可见。)
已解决:
我创造了
val userDataLoadingState = MutableSharedFlow<UserDataLoading>(replay = 0)
创建 ViewModel 时我设置了
state.userDataLoadingState.emit(UserDataLoading.LOADING)
我在 Activity
中收集数据lifecycleScope.launch {
mainSharedViewModel.state.userDataLoadingState.collect {
if (it == UserDataLoading.LOADED) {
bottomNavigationView.visibility = View.VISIBLE
} else {
bottomNavigationView.visibility = View.GONE
}
}
}
现在效果很好。之前不知道为什么不行