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
相关产品推荐
相关产品推荐

