修改Adapter时StateFlow.collect回调未触发问题排查
问题原因
StateFlow仅在值的引用发生变化时才会向collector发射新值。你使用MutableStateFlow<MutableSet<Taxonomy>>时,调用add/remove只是修改了MutableSet内部的元素,集合本身的引用并未改变,因此StateFlow无法感知到变化,也就不会触发collect回调。
解决方案
1. 重构ViewModel中的StateFlow定义
将可变集合替换为不可变的Set,确保每次修改都生成新的集合实例,触发StateFlow的发射逻辑:
// ViewModel内的字段定义 private val _selectedProvinces = MutableStateFlow<Set<Taxonomy>>(emptySet()) val selectedProvinces: StateFlow<Set<Taxonomy>> = _selectedProvinces private val _selectedAreas = MutableStateFlow<Set<Taxonomy>>(emptySet()) val selectedAreas: StateFlow<Set<Taxonomy>> = _selectedAreas private val _selectedSectors = MutableStateFlow<Set<Taxonomy>>(emptySet()) val selectedSectors: StateFlow<Set<Taxonomy>> = _selectedSectors
在ViewModel中添加修改集合的方法,每次操作都创建新的Set实例并emit:
// 添加元素 fun addProvince(taxonomy: Taxonomy) { _selectedProvinces.value = _selectedProvinces.value + taxonomy } fun addArea(taxonomy: Taxonomy) { _selectedAreas.value = _selectedAreas.value + taxonomy } fun addSector(taxonomy: Taxonomy) { _selectedSectors.value = _selectedSectors.value + taxonomy } // 移除元素 fun removeProvince(taxonomyId: String) { _selectedProvinces.value = _selectedProvinces.value.filterNot { it.id == taxonomyId }.toSet() } fun removeArea(taxonomyId: String) { _selectedAreas.value = _selectedAreas.value.filterNot { it.id == taxonomyId }.toSet() } fun removeSector(taxonomyId: String) { _selectedSectors.value = _selectedSectors.value.filterNot { it.id == taxonomyId }.toSet() }
2. 修改Adapter的点击事件逻辑
不再直接操作ViewModel的StateFlow值,转而调用ViewModel提供的修改方法:
holder.binding.root.onClick { if (isChecked(holder, taxonomyItem.type)) { isChecked.value = false holder.binding.rowCountryCheck.hide() when(taxonomyItem.type) { TaxonomyType.PROVINCE.value -> viewModel.removeProvince(taxonomyItem.id) TaxonomyType.AREA.value -> viewModel.removeArea(taxonomyItem.id) TaxonomyType.SECTOR.value -> viewModel.removeSector(taxonomyItem.id) } setLabelStyle(holder.binding.rowCountryTextTitle, R.attr.typography_text_list_item_16_unselected) notifyItemChanged(index) } else { isChecked.value = true holder.binding.rowCountryCheck.show() when(taxonomyItem.type) { TaxonomyType.PROVINCE.value -> viewModel.addProvince(taxonomyItem) TaxonomyType.AREA.value -> viewModel.addArea(taxonomyItem) TaxonomyType.SECTOR.value -> viewModel.addSector(taxonomyItem) } setLabelStyle(holder.binding.rowCountryTextTitle, R.attr.typography_text_list_item_16_selected) notifyItemChanged(index) } }
3. 简化Fragment的collect逻辑(可选)
由于现在StateFlow的泛型是不可变Set,可以简化原有的判断逻辑:
private fun checkIfEmptyAndSetButtonState(taxonomies: StateFlow<Set<Taxonomy>>) { lifecycleScope.launch { taxonomies.collect { setButtonEnabledState(it.isNotEmpty()) } } }
内容的提问来源于stack exchange,提问作者Albert Buigues
相关产品推荐
相关产品推荐

