You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:41:04