Android Kotlin:如何让Compose函数接收任意枚举类参数
让Compose对话框支持任意指定格式的枚举类参数
1. 定义通用接口统一枚举属性
先创建一个接口,规范所有目标枚举类的属性结构:
interface EnumItem { val id: Int val titleId: Int }
2. 让所有枚举类实现该接口
修改你的枚举类,实现上面的EnumItem接口:
enum class MyEnum1(override val id: Int, override val titleId: Int) : EnumItem { A1(0, R.string.a1), B1(1, R.string.b1), // ... 其他枚举值 } enum class MyEnum2(override val id: Int, override val titleId: Int) : EnumItem { A2(0, R.string.a2), B2(1, R.string.b2), // ... 其他枚举值 }
3. 实现支持泛型枚举的Compose对话框
提供两种实现方案,按需选择:
方案一:通过KClass传递枚举类(适配动态场景)
适合需要根据业务逻辑动态切换枚举类型的场景:
@Composable fun <T> ListDialog( onDismissRequest: () -> Unit, onItemSelected: (T) -> Unit, enumClass: KClass<T> ) where T : Enum<T>, T : EnumItem { // 获取枚举的所有常量值 val enumValues = enumClass.java.enumConstants ?: emptyArray() AlertDialog( onDismissRequest = onDismissRequest, title = { Text("选择选项") }, text = { LazyColumn { items(enumValues) { item -> Text( text = stringResource(item.titleId), modifier = Modifier .fillMaxWidth() .clickable { onItemSelected(item) onDismissRequest() } .padding(16.dp) ) } } }, confirmButton = { TextButton(onClick = onDismissRequest) { Text("取消") } } ) }
调用示例:
// 使用MyEnum1 ListDialog( onDismissRequest = { /* 处理对话框关闭逻辑 */ }, onItemSelected = { selectedItem -> // 处理选中逻辑,如获取selectedItem.id或titleId }, enumClass = MyEnum1::class ) // 使用MyEnum2 ListDialog( onDismissRequest = { /* 处理对话框关闭逻辑 */ }, onItemSelected = { selectedItem -> // 处理选中逻辑 }, enumClass = MyEnum2::class )
方案二:使用reified泛型(调用更简洁)
通过inline函数结合reified泛型,省去传递::class的步骤,代码更简洁:
@Composable inline fun <reified T> ListDialog( onDismissRequest: () -> Unit, onItemSelected: (T) -> Unit ) where T : Enum<T>, T : EnumItem { // 直接获取枚举所有常量值 val enumValues = enumValues<T>() AlertDialog( onDismissRequest = onDismissRequest, title = { Text("选择选项") }, text = { LazyColumn { items(enumValues) { item -> Text( text = stringResource(item.titleId), modifier = Modifier .fillMaxWidth() .clickable { onItemSelected(item) onDismissRequest() } .padding(16.dp) ) } } }, confirmButton = { TextButton(onClick = onDismissRequest) { Text("取消") } } ) }
调用示例:
// 使用MyEnum1 ListDialog<MyEnum1>( onDismissRequest = { /* 处理对话框关闭逻辑 */ }, onItemSelected = { selectedItem -> // 处理选中逻辑 } ) // 使用MyEnum2 ListDialog<MyEnum2>( onDismissRequest = { /* 处理对话框关闭逻辑 */ }, onItemSelected = { selectedItem -> // 处理选中逻辑 } )
核心说明
- 泛型约束
where T : Enum<T>, T : EnumItem确保传入的类型必须是枚举类,且具备id和titleId属性,保证代码安全。 - 两种方案都无需提前将枚举转换为
List<Pair<Int,Int>>,直接操作枚举对象更直观,也避免了类型转换的潜在问题。
内容的提问来源于stack exchange,提问作者LGstudio
相关产品推荐
相关产品推荐

