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

Jetpack Compose中如何获取DropdownMenuItem选中项的category_id

问题描述

我在Jetpack Compose中实现了一个下拉选择器,目前只能获取选中项的category_name,但需要同时获取对应的category_id。当前已经定义了两个mutableStateOf变量分别存储选中的标题和ID,想询问是否有其他实现方式,同时希望了解当选中如“Fruits”这类选项时,如何获取其对应的category_id(如11)并赋值给mSelectedCategoryId变量。

现有代码片段

状态变量

var mSelectedText by remember { mutableStateOf("") }
var mSelectedCategoryId by remember { mutableStateOf("") }

数据类

data class MainCategory(
    var category_id: String? = null,
    var category_name: String? = null,
    var categoryImage_url: String? = null,
    var category_priority: Int? = null
)

下拉菜单Composable

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainCatDownloadContent(
    mainCategories: Categories,
    mainCategoryOnClick: (categoryId: String, categoryTitle: String) -> Unit,
) {
    var mExpanded by remember { mutableStateOf(false) }
    val mCategories = mainCategories.mapTo(arrayListOf()){it.category_name}

    var mSelectedText by remember { mutableStateOf("") }
    var mSelectedCategoryId by remember { mutableStateOf("") }
    var mTextFieldSize by remember { mutableStateOf(Size.Zero) }

    // Up Icon when expanded and down icon when collapsed
    val icon = if (mExpanded)
        Icons.Filled.KeyboardArrowUp
    else
        Icons.Filled.KeyboardArrowDown

    Column(Modifier.padding(20.dp)) {
        OutlinedTextField(
            value = mSelectedText, onValueChange = { mSelectedText = it },
            modifier = Modifier
                .fillMaxWidth()
                .onGloballyPositioned { coordinates ->
                    mTextFieldSize = coordinates.size.toSize()
                },
            readOnly = true,
            label = { Text(text = "Select MainCategory")},
            trailingIcon = {
                Icon(icon,"contentDescription",
                    Modifier.clickable { mExpanded = !mExpanded })
            }
        )

        mCategories.forEach{ mainCategory ->
            DropdownMenuItem(onClick = {
                mSelectedText = mainCategory.toString()
                mExpanded = false }) {
                Text(text = mainCategory.toString())
            }
        }
    }
}

示例数据

[MainCategory(category_id=11, category_name=Fruits, categoryImage_url=https:www category_priority=1), 
MainCategory(category_id=22, category_name=Vegetable , categoryImage_url=https:www, category_priority=2), 
MainCategory(category_id=33, category_name=Greens, categoryImage_url=https:www, category_priority=3)]
解决方案

方式一:直接修改现有逻辑,关联ID与名称

当前你将mainCategories转换为仅存名称的列表,丢失了ID关联。可以直接遍历原始mainCategories生成下拉项,点击时直接获取对应ID:

修改后的Composable代码:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainCatDownloadContent(
    mainCategories: Categories,
    mainCategoryOnClick: (categoryId: String, categoryTitle: String) -> Unit,
) {
    var mExpanded by remember { mutableStateOf(false) }
    var mSelectedText by remember { mutableStateOf("") }
    var mSelectedCategoryId by remember { mutableStateOf("") }
    var mTextFieldSize by remember { mutableStateOf(Size.Zero) }

    val icon = if (mExpanded)
        Icons.Filled.KeyboardArrowUp
    else
        Icons.Filled.KeyboardArrowDown

    Column(Modifier.padding(20.dp)) {
        OutlinedTextField(
            value = mSelectedText, onValueChange = { mSelectedText = it },
            modifier = Modifier
                .fillMaxWidth()
                .onGloballyPositioned { coordinates ->
                    mTextFieldSize = coordinates.size.toSize()
                },
            readOnly = true,
            label = { Text(text = "Select MainCategory")},
            trailingIcon = {
                Icon(icon,"contentDescription",
                    Modifier.clickable { mExpanded = !mExpanded })
            }
        )

        // 遍历原始mainCategories,直接获取完整对象
        mainCategories.forEach { category ->
            DropdownMenuItem(onClick = {
                mSelectedText = category.category_name ?: ""
                mSelectedCategoryId = category.category_id ?: ""
                mExpanded = false
                mainCategoryOnClick(category.category_id ?: "", category.category_name ?: "")
            }) {
                Text(text = category.category_name ?: "")
            }
        }
    }
}

点击下拉项时,直接从MainCategory对象中提取ID和名称,无需额外匹配,避免名称重复导致的错误。

方式二:优化状态存储,保存完整选中对象

无需单独维护两个状态变量,直接存储选中的MainCategory对象,需要时从中提取所需字段:

修改后的代码:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainCatDownloadContent(
    mainCategories: Categories,
    mainCategoryOnClick: (categoryId: String, categoryTitle: String) -> Unit,
) {
    var mExpanded by remember { mutableStateOf(false) }
    // 直接存储选中的MainCategory对象,初始为null
    var mSelectedCategory by remember { mutableStateOf<MainCategory?>(null) }
    var mTextFieldSize by remember { mutableStateOf(Size.Zero) }

    val icon = if (mExpanded)
        Icons.Filled.KeyboardArrowUp
    else
        Icons.Filled.KeyboardArrowDown

    Column(Modifier.padding(20.dp)) {
        OutlinedTextField(
            // 从选中对象中提取名称
            value = mSelectedCategory?.category_name ?: "", 
            onValueChange = {}, // 只读状态,无需处理输入
            modifier = Modifier
                .fillMaxWidth()
                .onGloballyPositioned { coordinates ->
                    mTextFieldSize = coordinates.size.toSize()
                },
            readOnly = true,
            label = { Text(text = "Select MainCategory")},
            trailingIcon = {
                Icon(icon,"contentDescription",
                    Modifier.clickable { mExpanded = !mExpanded })
            }
        )

        mainCategories.forEach { category ->
            DropdownMenuItem(onClick = {
                mSelectedCategory = category
                mExpanded = false
                mainCategoryOnClick(category.category_id ?: "", category.category_name ?: "")
            }) {
                Text(text = category.category_name ?: "")
            }
        }
    }
}

这种方式的优势:

  • 减少状态变量数量,避免名称与ID不同步的问题
  • 后续需要使用MainCategory的其他字段(如图片URL)时,直接从选中对象获取即可,无需修改状态逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:01:08