iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

研究了這麼多 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 實作出來的。

自訂 Tooltip UI

由於 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 為主,太複雜反而會降低使用者體驗喔!

設定 Tooltip 的顯示及互動效果

除了設定 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

參考資料


上一篇
第 16 天:排版元件之 Surface、Box 與 Spacer
下一篇
第 18 天:Desktop 特有元件之 Tray
系列文
傳教士的 Compose for Desktop 耕讀筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言