今天詳細介紹 Card 的種類,以及實作時需要注意的事項。
@Composable
fun MyCard() {
Card() {
}
}
用到 Day8 的小技巧 ctrl+B
進到 androidx.compose.material3
可以瀏覽有哪些 Card 類型,看名稱有分成 Card
、ElevatedCard
、OutlinedCard
。
Card | ElevatedCard | OutlinedCard |
---|---|---|
這三種分別還有一組overloads
(function名稱相同,參數數量或類型不同),其中一組多了 onClick
, 和interactionSource
來處理觸控互動事件,由於是還在開發階段所以會有 @ExperimentalMaterial3Api
。
package androidx.compose.material3
@Composable
fun Card(
modifier: Modifier = Modifier,
shape: Shape = CardDefaults.shape,
colors: CardColors = CardDefaults.cardColors(),
elevation: CardElevation = CardDefaults.cardElevation(),
border: BorderStroke? = null,
content: @Composable ColumnScope.() -> Unit
) {
Surface(
modifier = modifier,
shape = shape,
color = colors.containerColor(enabled = true).value,
contentColor = colors.contentColor(enabled = true).value,
tonalElevation = elevation.tonalElevation(enabled = true, interactionSource = null).value,
shadowElevation = elevation.shadowElevation(enabled = true, interactionSource = null).value,
border = border,
) {
Column(content = content)
}
}
modifier
修飾符,他可以定義整個元件的擺放位置、點擊等等設定。
shap
定義邊角的形狀。
colors
定義卡片 Surface 卡面顏色、卡片上的字體顏色 content color。
elevation
元件高度。預設高度是由 cardElevation() 得到,我們可以一層一層往下找
最後在 androidx.compose.material3.tokens
找到定義好的高度dp。
internal object ElevationTokens {
val Level0 = 0.0.dp
val Level1 = 1.0.dp
val Level2 = 3.0.dp
val Level3 = 6.0.dp
val Level4 = 8.0.dp
val Level5 = 12.0.dp
}
什麼是 token 呢?
這裡的 token 指的是 design token ,我個人把它翻譯成“設計標籤”,他把靜態數值如顏色#E8DEF8
或高度12.0.dp
存在有名字的變數裡,名字就像標籤一樣,使用時可以直觀地知道這個值的用途,形成一個有系統的設計。
border
邊框,這裡不要求要輸入
content
要被 Card 包住的 composable,這裡他用了 ColumnScope的排列方式,相當用Card包住的元素會以上到下的方式去做排列。
@ExperimentalMaterial3Api
@Composable
fun Card(
//點選 card 內部範圍
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = CardDefaults.shape,
colors: CardColors = CardDefaults.cardColors(),
elevation: CardElevation = CardDefaults.cardElevation(),
border: BorderStroke? = null,
//紀錄當前狀態,如拖曳、按壓
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable ColumnScope.() -> Unit
) {
//...
}
onClick
當卡片被點執行被傳入的方法interactionSource
他可以記住卡片當前互動的狀態,讓我們在觀察到不同的狀態時去做處理,常用在拖曳(dragged)和按壓 (pressed)。在本專案會用到需要監聽卡片拖曳或按壓的狀態 所以都會選擇帶有 onclick 和 interactionSource 的卡片。
接下來我們來看看 ElevatedCard
@ExperimentalMaterial3Api
@Composable
fun ElevatedCard(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = CardDefaults.elevatedShape,
colors: CardColors = CardDefaults.elevatedCardColors(),
elevation: CardElevation = CardDefaults.elevatedCardElevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable ColumnScope.() -> Unit
) = Card(
onClick = onClick,
modifier = modifier,
enabled = enabled,
shape = shape,
colors = colors,
elevation = elevation,
border = null,
interactionSource = interactionSource,
content = content
)
我們會發現它回傳的是 Card 的變化型,差別只在 shap
colors
elevation
call 了不同的 token,知道這個很重要,如果沒觀察到這個變化我可能會分別使用Card
、ElevatedCard
、OutlinedCard
三種不同的 Card,但如果只要改變參數值shap
colors
elevation
就能達到效果的話就能減少UI需要渲染的範圍。
而 OutlinedCard
也和 ElevatedCard
一樣也是更改Card
部分參數,這裡就不多贅述了。
Modifier.clickable()
和 onClick: () -> Unit
的差別Modifier 可以控制整個元件是否可以點擊,那這樣和帶有 onClick() 方法的效果差在哪呢?
上方是 Modifier.clickable()
的效果,會發現他會聯同圓角外的範圍一同有點下去的陰影效果。
而使用onClick: () -> Unit
則是會在圓角內部做出陰影效果外還有漣漪效果。
下面這種比較符合使用者習慣,別用錯囉。
今天整理了 M3 中的三種 Card ,並從參數觀察三種卡片的差別。最後帶到兩種點擊的效果差異。
今日運動
瑜伽 50 分鐘