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

如何从Manufacturers模块获取数据填充ExposedDropdownMenu?

实现示例:用厂商数据填充ExposedDropdownMenu并关联产品表

1. Room 实体与DAO定义

先确保你的Room实体和DAO包含必要的核心方法:

厂商实体

@Entity(tableName = "manufacturers")
data class Manufacturer(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String
)

产品实体(关联厂商ID)

@Entity(
    tableName = "products",
    foreignKeys = [ForeignKey(
        entity = Manufacturer::class,
        parentColumns = ["id"],
        childColumns = ["manufacturer_id"],
        onDelete = ForeignKey.CASCADE
    )]
)
data class Product(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String,
    val price: Double,
    @ColumnInfo(name = "manufacturer_id") val manufacturerId: Int
)

DAO 接口

@Dao
interface AppDao {
    // 获取所有厂商的Flow,实时监听数据变化
    @Query("SELECT * FROM manufacturers ORDER BY name ASC")
    fun getAllManufacturers(): Flow<List<Manufacturer>>

    // 插入新产品
    @Insert
    suspend fun insertProduct(product: Product)
}

2. Repository 层

封装数据操作,统一暴露给ViewModel:

class AppRepository(private val dao: AppDao) {
    val allManufacturers: Flow<List<Manufacturer>> = dao.getAllManufacturers()

    suspend fun insertProduct(product: Product) {
        dao.insertProduct(product)
    }
}

3. ViewModel 层

管理UI状态,处理厂商列表和选中逻辑:

class AddProductViewModel(private val repository: AppRepository) : ViewModel() {
    // 将厂商Flow转为StateFlow,供Compose观察
    val manufacturers = repository.allManufacturers
        .stateIn(
            viewModelScope,
            SharingStarted.WhileSubscribed(5000),
            emptyList()
        )

    // 选中的厂商状态
    private val _selectedManufacturer = mutableStateOf<Manufacturer?>(null)
    val selectedManufacturer = _selectedManufacturer.asState()

    // 更新选中的厂商
    fun onManufacturerSelected(manufacturer: Manufacturer) {
        _selectedManufacturer.value = manufacturer
    }

    // 提交新产品
    suspend fun submitProduct(productName: String, price: Double) {
        selectedManufacturer.value?.let { manufacturer ->
            val product = Product(
                name = productName,
                price = price,
                manufacturerId = manufacturer.id
            )
            repository.insertProduct(product)
        }
    }
}

4. Compose UI 实现(ExposedDropdownMenu)

构建添加产品界面,集成厂商选择下拉菜单:

@Composable
fun AddProductScreen(viewModel: AddProductViewModel = hiltViewModel()) {
    val manufacturers by viewModel.manufacturers.collectAsState()
    val selectedManufacturer by viewModel.selectedManufacturer
    val (productName, onProductNameChange) = remember { mutableStateOf("") }
    val (priceText, onPriceTextChange) = remember { mutableStateOf("") }
    val price = priceText.toDoubleOrNull() ?: 0.0

    // 下拉菜单展开状态
    val (expanded, setExpanded) = remember { mutableStateOf(false) }

    Scaffold(topBar = { TopAppBar(title = { Text("添加新产品") }) }) { padding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            // 产品名称输入框
            OutlinedTextField(
                value = productName,
                onValueChange = onProductNameChange,
                label = { Text("产品名称") },
                modifier = Modifier.fillMaxWidth()
            )

            // 价格输入框
            OutlinedTextField(
                value = priceText,
                onValueChange = onPriceTextChange,
                label = { Text("产品价格") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                modifier = Modifier.fillMaxWidth()
            )

            // 厂商选择下拉菜单
            ExposedDropdownMenuBox(
                expanded = expanded,
                onExpandedChange = { setExpanded(!expanded) }
            ) {
                OutlinedTextField(
                    readOnly = true,
                    value = selectedManufacturer?.name ?: "选择厂商",
                    onValueChange = {},
                    label = { Text("厂商") },
                    trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
                    modifier = Modifier
                        .fillMaxWidth()
                        .menuAnchor()
                )

                ExposedDropdownMenu(
                    expanded = expanded,
                    onDismissRequest = { setExpanded(false) }
                ) {
                    if (manufacturers.isEmpty()) {
                        DropdownMenuItem(
                            text = { Text("暂无厂商数据") },
                            onClick = { setExpanded(false) },
                            enabled = false
                        )
                    } else {
                        manufacturers.forEach { manufacturer ->
                            DropdownMenuItem(
                                text = { Text(manufacturer.name) },
                                onClick = {
                                    viewModel.onManufacturerSelected(manufacturer)
                                    setExpanded(false)
                                }
                            )
                        }
                    }
                }
            }

            // 提交按钮
            Button(
                onClick = {
                    viewModelScope.launch {
                        viewModel.submitProduct(productName, price)
                        // 提交成功后可清空输入或返回上一页
                    }
                },
                enabled = productName.isNotBlank() && price > 0 && selectedManufacturer != null,
                modifier = Modifier.fillMaxWidth()
            ) {
                Text("添加产品")
            }
        }
    }
}

额外提示

  • 建议用Hilt或其他依赖注入框架管理ViewModel和Repository实例,避免生命周期问题
  • 可补充输入校验逻辑,比如价格格式错误、未选择厂商时的Toast提示
  • 若需要支持厂商搜索,可在ExposedDropdownMenu上方添加搜索输入框,过滤厂商列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:12:03