iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0

在實作 Desktop App 時,有一種很特別的 UI 是 Tray,也就是在功能列上的小圖示。許多 App 會把一些小工具收在 Tray 裡,方便使用者可以隨時取用,做為 Window 之外的延伸。甚至有些 App 根本就沒有 Window,直接透過 Tray 上的選單跟使用者互動。Tray 元件是 Desktop 環境才有的設計,今天的耕讀筆記就來研究一下其用法及設定值。

Tray 元件

我們要在應用程式一啟動的時候就宣告一個 Tray 元件,一般會直接宣告在 Window 元件之前,若 App 沒有 Window 的設計,也可以只宣告 Tray 即可。Tray 元件提供四個設定值來調整其外觀及行為:

fun main() = application {
    val trayState = rememberTrayState()
    
    Tray(
        icon = painterResource("..."),
        state = trayState,
        tooltip = "MyApp Tray",
        onAction = { /* ... */ }
    ) {
        Menu(text = "File") {
            Item(text = "Open", onClick = { /* ... */ })
        }
        Menu("Edit") {
            Item(text = "Cut", onClick = { /* ... */ })
            Item(text = "Copy", onClick = { /* ... */ })
            Item(text = "Paste", onClick = { /* ... */ })
        }
    }
}
  • icon:設定 Tray 在系統工具列上的圖示,支援傳入 Painter 實例。
  • state:紀錄 Tray 的狀態,並可用於發送 Notification
  • tooltip:設定 Tray 的工具列提示,當滑鼠停在圖示上約三秒時顯示。
  • onAction:當使用者以滑鼠點擊 Tray 時觸發的事件。

在使用 Tray 時,需注意以下四點:

  1. icon 參數如同我們熟悉的其他元件,可用 painterResource() 或向量繪製的方式傳入。
  2. 參數 state 預設是可以不用傳入的,但一般為了方便取出與修改,會自行宣告 val trayState = rememberTrayState() 後再傳入。
  3. onAction 事件在不同作業系統上的觸發條件是不同的,在 Windows 上是雙擊圖示、在 macOS 上是右鍵單擊圖示。
  4. 其實 Tray 有第五個參數 menu,但因為 menu 接受 Function Parameter 且是最後一個參數,所以依 Kotlin 慣例可以直接放在 Lambda 裡。在上面的範例裡,因為要做出階層選單,所以用了 MenuItem 兩種元件。若只有一層選單的話,可以只用 Item 元件實作。

Tray 現階段的限制

Compose for Desktop 雖然提供簡單易用的 Tray 元件,但現階段能做的功能仍很有限,官方僅示範功能選單的範例,若要做到市面上許多 Tray App 那種自訂樣式的視窗,只靠 @Composable 元件是做不到的,得自行呼叫底層的 Swing API 進行實作。

參考資料


上一篇
第 17 天:Desktop 特有元件之 Tooltip
下一篇
第 19 天:Desktop 特有元件之 Notification
系列文
傳教士的 Compose for Desktop 耕讀筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言