Jetpack Compose collectAsState() 不适用于 Flow combine()
Jetpack Compose collectAsState() does not work with Flow combine()
我想从 Firestore 加载数据,并使用 Flow 将其与其他数据合并 combine()
视图模型:
private val userCurrentProject = MutableStateFlow("")
val projects = repository
.listenToProject() //listening via Firestore snapshot listener, no problem here
.combine(userCurrentProject) { projects, currentProjectName ->
// combine works and called normally
projects.map { project ->
project.apply {
isUserCurrentProject = name == currentProjectName
}
}
}
fun setCurrentProject(projectName: String) = viewModelScope.launch {
userCurrentProject.emit(projectName)
}
可组合项:
fun ProjectListScreen(navController: NavHostController, viewModel: ProjectsViewModel) {
val projects by viewModel.projects.collectAsState(initial = emptyList())
// This is where the problem started
// Lazy column not updated when projects flow is emitting new value
// Even Timber log does not called
Timber.d("Projects : $projects")
LazyColumn {
items(projects) { project ->
ProjectItem(project = project) {
currentlySelectedProject = project
scope.launch { bottomSheetState.show() }
}
}
}
flow
正常,但是state
一直没有更新,不知道为什么。也许这是 collectAsState()
的问题?
但是当我导航到下一个屏幕(添加新项目屏幕)然后按返回键 (popBackStack) 时状态会更新
注意:使用 asLiveData()
和 observeAsState()
也不起作用。
我终于找到了答案
罪魁祸首是 custom object/class 的状态与 primitives (String, Int,等等)
对于状态对象,你需要使用copy()
所以我只是更改了 ViewModel 的这一部分
val projects = repository
.listenProject()
.combine(userCurrentProject) { projects, currentProjectName ->
projects.map { project ->
// use copy instead of apply
val isCurrentProject = project.name == currentProjectName
project.copy(isUserCurrentProject = isCurrentProject)
}
}
我想从 Firestore 加载数据,并使用 Flow 将其与其他数据合并 combine()
视图模型:
private val userCurrentProject = MutableStateFlow("")
val projects = repository
.listenToProject() //listening via Firestore snapshot listener, no problem here
.combine(userCurrentProject) { projects, currentProjectName ->
// combine works and called normally
projects.map { project ->
project.apply {
isUserCurrentProject = name == currentProjectName
}
}
}
fun setCurrentProject(projectName: String) = viewModelScope.launch {
userCurrentProject.emit(projectName)
}
可组合项:
fun ProjectListScreen(navController: NavHostController, viewModel: ProjectsViewModel) {
val projects by viewModel.projects.collectAsState(initial = emptyList())
// This is where the problem started
// Lazy column not updated when projects flow is emitting new value
// Even Timber log does not called
Timber.d("Projects : $projects")
LazyColumn {
items(projects) { project ->
ProjectItem(project = project) {
currentlySelectedProject = project
scope.launch { bottomSheetState.show() }
}
}
}
flow
正常,但是state
一直没有更新,不知道为什么。也许这是 collectAsState()
的问题?
但是当我导航到下一个屏幕(添加新项目屏幕)然后按返回键 (popBackStack) 时状态会更新
注意:使用 asLiveData()
和 observeAsState()
也不起作用。
我终于找到了答案
罪魁祸首是 custom object/class 的状态与 primitives (String, Int,等等)
对于状态对象,你需要使用copy()
所以我只是更改了 ViewModel 的这一部分
val projects = repository
.listenProject()
.combine(userCurrentProject) { projects, currentProjectName ->
projects.map { project ->
// use copy instead of apply
val isCurrentProject = project.name == currentProjectName
project.copy(isUserCurrentProject = isCurrentProject)
}
}