Card
Card 是 COUI 中的基础容器组件,用于承载相关内容和操作。它提供了具有 COUI 风格的卡片容器,适用于信息展示、内容分组等场景。支持静态显示和交互式两种模式。
引入
kotlin
import io.github.suqi8.coui.kmp.basic.Card
import io.github.suqi8.coui.kmp.utils.PressFeedbackType // 如果使用交互式卡片基本用法
Card 组件可以用于包装和组织内容(静态卡片):
kotlin
Card {
Text("这是卡片内容")
}属性
Card 属性
| 属性名 | 类型 | 说明 | 默认值 | 是否必须 | 适用范围 |
|---|---|---|---|---|---|
| modifier | Modifier | 应用于卡片的修饰符 | Modifier | 否 | 所有 |
| cornerRadius | Dp | 卡片圆角半径 | CardDefaults.CornerRadius | 否 | 所有 |
| insideMargin | PaddingValues | 卡片内部边距 | CardDefaults.InsideMargin | 否 | 所有 |
| colors | CardColors | 卡片颜色配置 | CardDefaults.defaultColors() | 否 | 所有 |
| pressFeedbackType | PressFeedbackType | 按压反馈类型 | PressFeedbackType.Tint | 否 | 交互式 |
| showIndication | Boolean | 显示点击指示效果 | false | 否 | 交互式 |
| holdDownState | Boolean | 卡片是否处于按下状态 | false | 否 | 交互式 |
| onClick | (() -> Unit)? | 点击事件回调 | null | 否 | 交互式 |
| onLongPress | (() -> Unit)? | 长按事件回调 | null | 否 | 交互式 |
| content | @Composable ColumnScope.() -> Unit | 卡片内容区域的可组合函数 | - | 是 | 所有 |
注意
部分属性仅在创建可交互的卡片时可用!
CardDefaults 对象
CardDefaults 对象提供了卡片组件的默认值和颜色配置。
常量
| 常量名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| CornerRadius | Dp | 卡片的圆角半径 | 12.dp |
| InsideMargin | PaddingValues | 卡片的内部边距 | PaddingValues(0.dp) |
方法
| 方法名 | 类型 | 说明 |
|---|---|---|
| defaultColors() | CardColors | 卡片的默认颜色 |
CardColors 类
| 属性名 | 类型 | 说明 |
|---|---|---|
| color | Color | 卡片的背景颜色 |
| contentColor | Color | 卡片的内容颜色 |
| pressedColor | Color | 按压时背景过渡到的颜色(Tint 反馈使用) |
PressFeedbackType 选项
| 选项 | 说明 |
|---|---|
| None | 无按压反馈 |
| Tint | 按压或保持按下时背景过渡到 pressedColor(COUI 卡片按压反馈,默认) |
| Sink | 按压时轻微下沉(缩小) |
| Tilt | 按压时根据触摸位置倾斜 |
进阶用法
自定义样式卡片
kotlin
Card(
cornerRadius = 8.dp,
insideMargin = PaddingValues(16.dp),
colors = CardDefaults.defaultColors(
color = COUITheme.colorScheme.primaryVariant
),
) {
Text("自定义样式卡片")
}内容丰富的卡片
kotlin
Card(
modifier = Modifier.padding(16.dp),
insideMargin = PaddingValues(16.dp)
) {
Text(
text = "卡片标题",
style = COUITheme.textStyles.title2
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "这是卡片的详细内容描述,可以包含多行文本信息。"
)
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
) {
TextButton(
text = "取消",
onClick = { /* 处理取消事件 */ }
)
Spacer(modifier = Modifier.width(8.dp))
TextButton(
text = "确定",
colors = ButtonDefaults.textButtonColorsPrimary(), // 使用主题颜色
onClick = { /* 处理确认事件 */ }
)
}
}列表中的卡片
kotlin
LazyColumn {
items(5) { index ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
insideMargin = PaddingValues(16.dp)
) {
Text("列表项 ${index + 1}")
}
}
}可交互的卡片
kotlin
Card(
modifier = Modifier.padding(16.dp),
// pressFeedbackType 默认为 PressFeedbackType.Tint:按压时背景过渡到
// CardColors.pressedColor(COUI 卡片按压反馈)
onClick = { /* 处理点击事件 */ },
onLongPress = { /* 处理长按事件 */ }
) {
Text("可交互的卡片")
}kotlin
Card(
modifier = Modifier.padding(16.dp),
pressFeedbackType = PressFeedbackType.Sink, // 设置按压反馈为下沉动画效果
showIndication = true, // 显示点击时的视觉反馈效果
onClick = { /* 处理点击事件 */ },
) {
Text("可交互的卡片(下沉)")
}卡片组内的行位置
COUI 会给卡片组的圆角外边缘增加 coui_list_card_head_or_tail_padding(2dp)。给 Card 内堆叠的 preference 行传入 CardListPosition,即可让每一行只在真正带圆角的那一侧获得该内边距。 CardListPosition.None(默认值)不增加任何内边距,因此现有调用点不受影响。
| 位置 | 顶部额外内边距 | 底部额外内边距 | 合计 |
|---|---|---|---|
None(默认) | 0dp | 0dp | +0dp |
Head | 2dp | 0dp | +2dp |
Middle | 0dp | 0dp | +0dp |
Tail | 0dp | 2dp | +2dp |
Full(唯一一行) | 2dp | 2dp | +4dp |
遍历列表时可用 cardListPositionOf(index, count) 推导位置。它对应 COUI 的 COUICardListHelper.getPositionInGroup(int, int),当 count == 1 时返回 Full。
kotlin
val options = listOf("每天", "仅工作日", "从不")
Card {
options.forEachIndexed { index, option ->
if (index > 0) HorizontalDivider(Modifier.padding(horizontal = 16.dp))
MarkPreference(
title = option,
checked = selected == index,
onClick = { selected = index },
cardListPosition = cardListPositionOf(index, options.size),
)
}
}
