研究了這麼多 Compose 元件,基本上這些元件不論是在外觀、行為和程式碼上,都與 Android 上相同。不過,畢竟 Desktop 環境跟 Mobile 環境還是有先天性上的不同,為了滿足 Desktop 上的需要,Compose for Desktop 專案裡,有一些是 Desktop 才有的元件。在接下來幾天的耕讀筆記,會開始著手研究這些元件,首先第一個是 Tooltip。
TooltipArea
元件Tooltip 是指在 Desktop 操作時,當滑鼠停在某個 UI 元件上超過一段時間後,會彈出的一個輔助標籤,說明滑鼠碰到的元件功能。換成 Web 開發的說法,就是當 MouseOver 或是 CSS 裡的 hover 狀態。由於 Mobile 上並沒有游標,也就沒有這樣的元件。
Compose for Desktop 依循著相同的元件設計概念,Tooltip 本身並沒有 UI,要實作出 Tooltip 的效果,要先用 TooltipArea
元件括住要有 Tooltip 互動的元件,形成一個滑鼠感應區,再將 Tooltip 的 UI 以其他元件實作後,以 tooltip
參數傳入 TooltipArea
元件內:
TooltipArea(
tooltip = {
Surface(
modifier = Modifier.shadow(4.dp),
color = Color(255, 255, 210),
shape = RoundedCornerShape(4.dp),
) {
Text(
text = "...",
modifier = Modifier.padding(10.dp),
)
}
},
) {
Button(onClick = { /* ... */ }) {
Text(text = "...")
}
}
從上面這個簡單的例子裡可以看到,Button
是要增加 Tooltip 互動的主體,Tooltip 的 UI 則是用 Surface
搭配 Text
實作出來的。
由於 TooltipArea
並沒有預設的 UI,而是透過 tooltip
參數由外部傳入,因此我們可以自行設定複雜的 @Composable
元件做為 Tooltip。
TooltipArea(
tooltip = {
MyGorgeousToolTip(
title = "...",
description = "...",
imageUrl = "..."
)
},
) {
Button(onClick = { /* ... */ }) {
Text(text = "...")
}
}
@Composable
fun MyGorgeousToolTip(
title: String,
description: String,
imageUrl: String
) {
Surface(
modifier = Modifier.width(300.dp).height(100.dp),
shape = RoundedCornerShape(8.dp),
elevation = 7.dp,
) {
Row {
AsyncImage(
load = { loadImageBitmap(imageUrl) },
painterFor = { remember { BitmapPainter(it) } },
contentDescription = "Photo",
contentScale = ContentScale.Crop,
modifier = Modifier.size(100.dp).padding(end = 12.dp),
)
Column(
modifier = Modifier.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
) {
Text(
text = title,
fontSize = 15.sp,
)
Text(
text = description,
fontSize = 8.sp,
modifier = Modifier.padding(vertical = 8.dp),
)
}
}
}
}
在上例裡,我們把之前用 Surface
做出的 UI 獨立成一個 @Composable
元件,然後在傳入 tooltip
參數時,直接呼叫元件名稱,如此可以讓 UI 獨立出來而不會讓 TooltipArea
的程式碼太長而不好閱讀。
當然啦!筆者這樣做只是概念驗證,一般 Tooltip 都是以簡單輕巧的 UI 為主,太複雜反而會降低使用者體驗喔!
除了設定 UI 外,TooltipArea
還有幾個參數可以微調顯示效果:
TooltipArea(
tooltip = { /* ... */ },
modifier = Modifier.padding(start = 40.dp),
delayMillis = 600,
tooltipPlacement = TooltipPlacement.CursorPoint(
alignment = Alignment.BottomEnd,
offset = DpOffset(30.dp, 30.dp)
)
) {
Button(onClick = { }) {
Text(text = "...")
}
}
modifier
:若要微調 TooltipArea
的樣式設定,可以透過 Modifier
調整,比方說內距(padding
)。delayMillis
:設定當滑鼠移入感應區,停涉多少時間後顯示 Tooltip,預設為 500 ms。tooltipPlacement
:傳入一個設定 TooltipPlacement
介面,再透過 CursorPoint()
方式指定 Tooltip 的放置位置。alignment
可以設定 Tooltip 要對齊在滑鼠游標九宮格的那個方位,offset
則是 Tooltip 與滑鼠游標的距離差,透過 DpOffset
傳入 X、Y 兩個方向的 dp
長度即可,預設是 DpOffset(0.dp, 16.dp)
,若有歸零也可以直接寫 DpOffset.Zero
。