Jetpack Compose实现药丸形状可组合组件方案问询
Jetpack Compose 实现药丸形状切换组件(Material 3)
实现方式说明
Material 3确实没有原生提供这类药丸形状的切换组件,可以用RadioButton实现,但需要大量样式定制,反而不如直接用可点击布局组件组合更高效直观——你当前用Button的思路方向是对的,只需修正细节问题即可。
你的代码问题修正与优化
你提供的代码已经具备核心框架,但存在几处明显问题:
- 循环中
titleText硬编码为"English",导致两个选项显示内容重复 - 使用
ElevatedButton会自带阴影,不符合药丸组件的简洁风格 - 部分参数可以简化,比如文本颜色可根据选中状态自动切换
以下是修正优化后的代码:
@Composable fun PillToggleSample() { val selectedIndex = remember { mutableStateOf(0) } val containerBg = Color.Red.copy(alpha = 0.2f) val optionList = listOf("English", "Arabic") Row( modifier = Modifier .fillMaxWidth() .widthIn(max = 600.dp) .padding(horizontal = 20.dp, vertical = 28.dp) .background(containerBg, RoundedCornerShape(25.dp)) .wrapContentHeight(), verticalAlignment = Alignment.CenterVertically ) { optionList.forEachIndexed { index, title -> PillToggleItem( modifier = Modifier.weight(1f), isSelected = selectedIndex.value == index, title = title, onClick = { selectedIndex.value = index } ) } } } @Composable fun PillToggleItem( modifier: Modifier, isSelected: Boolean, title: String, onClick: () -> Unit ) { // 用Surface替代ElevatedButton,避免不必要的阴影 Surface( onClick = onClick, color = if (isSelected) Color.Red else Color.Transparent, shape = RoundedCornerShape(25.dp), modifier = modifier .padding(2.dp) ) { Text( text = title, modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), color = if (isSelected) Color.White else Color.Black, lineHeight = 16.sp ) } }
关键实现要点
- 外层
Row作为整体容器,设置圆角背景实现药丸外框效果 - 用
remember保存选中选项的索引,维护组件状态 - 每个选项用
Surface(或Box)实现可点击区域,根据选中状态切换背景色 - 通过
weight(1f)让每个选项平分容器宽度,保证布局均匀
内容的提问来源于stack exchange,提问作者Farooq Arshed
相关产品推荐
相关产品推荐

