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

Room查询列表为空,无法填充DropDownMenu问题求助

问题定位与修复方案

你的核心问题是ViewModel中从DAO获取的Bullet列表没有同步到UI依赖的AmmoState里,导致UI拿到的state.bulletName始终是初始空列表。另外还有几处细节需要完善,以下是分步修复:

1. 同步Bullet列表到AmmoState

ViewModel里单独的bulletName StateFlow没有和_state关联,UI自然拿不到数据。修改ViewModel,把DAO返回的Flow结果同步到AmmoState:

@OptIn(ExperimentalCoroutinesApi::class)
class AmmoViewModel(
    private val dao: BBDao,
) : ViewModel() {
    private val _state = mutableStateOf(AmmoState())
    val state = _state.asStateFlow()

    init {
        // 收集Bullet列表,更新到状态中
        viewModelScope.launch {
            dao.getBulletNames().collect { bulletNames ->
                _state.update { it.copy(bulletName = bulletNames) }
            }
        }
    }

    fun onEvent(event: AmmoEvent) {
        when (event) {
            AmmoEvent.ShowDialog -> {
                _state.update {
                    it.copy(
                        isAddingAmmo = true,
                        ammoBulletName = "",
                    )
                }
            }
            AmmoEvent.HideDialog -> {
                _state.update { it.copy(isAddingAmmo = false) }
            }
            is AmmoEvent.SetAmmoName -> {
                _state.update { it.copy(ammoName = event.name) }
            }
            is AmmoEvent.SetAmmoBulletName -> {
                _state.update { it.copy(ammoBulletName = event.bulletName) }
            }
            AmmoEvent.SaveAmmo -> {
                viewModelScope.launch {
                    dao.insertAmmo(
                        Ammo(
                            ammoName = _state.value.ammoName,
                            ammoBulletName = _state.value.ammoBulletName
                        )
                    )
                    _state.update { it.copy(isAddingAmmo = false, ammoName = "") }
                }
            }
        }
    }
}

2. 完善状态与事件定义

你的AmmoState和AmmoEvent缺少必要字段/事件类型,补充完整:

// 补充AmmoState缺失的字段
data class AmmoState(
    val bulletName: List<BulletNames> = emptyList(),
    val ammoName: String = "",
    val ammoBulletName: String = "",
    val isAddingAmmo: Boolean = false
)

// 补充AmmoEvent缺失的事件
sealed interface AmmoEvent {
    data object ShowDialog : AmmoEvent
    data object HideDialog : AmmoEvent
    data object SaveAmmo : AmmoEvent
    data class SetAmmoName(val name: String) : AmmoEvent
    data class SetAmmoBulletName(val bulletName: String) : AmmoEvent
}

3. 确认Bullet表存在数据

如果数据库里Bullet表本身是空的,查询结果当然为空。可以在数据库初始化时预插测试数据:

// 创建数据库时添加回调
val db = Room.databaseBuilder(
    context,
    BBDatabase::class.java,
    "bb_database"
).addCallback(object : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        // 预插测试Bullet数据
        GlobalScope.launch {
            dao.insertBullet(Bullet("9mm"))
            dao.insertBullet(Bullet(".45 ACP"))
        }
    }
}).build()

也可以用Android Studio的App Inspection直接查看数据库表内容。

4. 修复Dialog下拉菜单显示问题

Dialog里用item.toString()会显示BulletNames(bulletName=xxx),改成直接取字段值:

DropdownMenuItem(
    text = { Text(text = item.bulletName) },
    onClick = {
        expanded = false
        selectedBullet = item.bulletName
        onEvent(AmmoEvent.SetAmmoBulletName(item.bulletName))
    },
)

5. UI层正确接收状态

确保AmmoScreen观察ViewModel的StateFlow:

@Composable
fun AmmoScreen(
    viewModel: AmmoViewModel = viewModel()
){
    val state by viewModel.state.collectAsState()
    Scaffold (
        floatingActionButton = {
            FloatingActionButton(onClick = {
                viewModel.onEvent(AmmoEvent.ShowDialog)
            }) {
                Icon(imageVector = Icons.Default.Add, contentDescription = "Add Ammo")
            }
        },
        modifier = Modifier.padding(16.dp)
    ) {_ ->
        if(state.isAddingAmmo){
            AddAmmoDialog(state = state, onEvent = viewModel::onEvent)
        }
    }
}

内容的提问来源于stack exchange,提问作者Kurtis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:27:04