與資訊方塊互動

資訊方塊不只會顯示資訊,還能提供互動功能。如要讓 textButton() 等元素回應輕觸動作,請使用 clickable() 產生點擊處理常式,並將其與版面配置元素建立關聯。

您可以透過兩種主要方式設定 Clickable 以觸發動作:

  1. 直接啟動活動:如果需要立即開啟活動,請使用 launchAction()
  2. 委派至資訊方塊服務:使用 loadAction() 觸發 TileService 中的邏輯。這是更具彈性的做法,可讓您重新整理資訊方塊的內容、更新其狀態,或啟動更複雜的活動。

啟動匯出的活動

如果使用者輕觸後應立即啟動活動,請使用 launchAction()。提供 ComponentName 來識別活動。活動必須匯出。使用這個方法,您可以透過動作傳遞 Intent 額外項目。不過,您無法設定自訂 Intent 標記。

以下範例說明如何建立 Clickable,以便透過兩個額外項目 nameage 啟動 TileActivity

textButton(
    labelContent = {
        text("launchAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        launchAction(
            ComponentName(
                "com.example.wear",
                "com.example.wear.snippets.m3.tile.TileActivity",
            ),
            mapOf(
                "name" to ActionBuilders.stringExtra("Bartholomew"),
                "age" to ActionBuilders.intExtra(21),
            ),
        )
    ),
)

在啟動的活動中,從意圖額外項目擷取值:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // When this activity is launched from the tile InteractionLaunchAction,
    // "name" will be "Bartholomew" and "age" will be 21
    val name = intent.getStringExtra("name")
    val age = intent.getStringExtra("age")

    // ...
}

處理資訊方塊服務中的互動

如要提供更彈性的互動體驗,請使用 loadAction()。當使用者輕觸以 loadAction 設定的元素時,系統會重新叫用您的 TileService.onTileRequest()。這樣一來,您就能在服務中執行邏輯,以便更新圖塊、變更圖塊狀態,以及執行更複雜的工作。

重新整理資訊方塊內容

loadAction 最簡單的用途就是傳送重新整理信號。呼叫不含任何引數的 loadAction。輕觸後,系統會呼叫 onTileRequest(),讓服務傳回含有更新內容的新版面配置。

textButton(
    onClick = clickable(loadAction()),
    labelContent = { text("Refresh".layoutString) },
)

區分多個互動式元素

如果資訊方塊包含多個互動式元素,您可以使用 Clickable 修飾符將 ID 關聯:

onTileRequest() 中,您可以使用 requestParams.currentState.lastClickableId 檢查此 ID,決定要執行哪些動作。

範例:使用深層連結啟動活動

此模式非常適合使用深層連結啟動活動。使用者輕觸重新載入圖塊,您的服務會檢查 ID,然後啟動新的活動。如要控制返回堆疊,請使用 TaskStackBuilder 為使用者提供更優質的導覽體驗。使用者輕觸元素後,系統會直接將他們導向深層連結畫面 (範例中的 message_detail/1 畫面)。由於使用了 .addNextIntentWithParentStack(),因此父項活動也會新增至返回堆疊。也就是說,如果使用者滑動返回,他們會向上瀏覽應用程式的主畫面 (範例中的 MessageList),而不是立即退出至資訊方塊。再次向後滑動即可返回資訊方塊。

接著,在 TileActivity 中,將導覽設定與 googleandroidsnippets://app/message_detail/{id} 模式相符。

使用 TaskStackBuilder,為使用者提供更優質的導覽體驗。使用者輕觸元素後,系統會直接將他們導向深層連結畫面,在本例中就是 message_detail/1 畫面。由於使用了 .addNextIntentWithParentStack(),因此父項活動也會新增至返回堆疊。也就是說,如果使用者滑動返回,他們會向上瀏覽應用程式的主畫面 (在本例中為 MessageList),而不是立即退出並前往資訊方塊。再次向後滑動即可返回資訊方塊。

更新資訊方塊內的狀態

資訊方塊含有 StateBuilders.State 物件,可儲存鍵/值組合,並在重新載入時保留。當使用者與資訊方塊互動時,您可以使用 loadAction() 更新此狀態。

如要這麼做,請將 DynamicDataMap 傳遞至包含新狀態值的 loadAction()

textButton(
    labelContent = {
        text("loadAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        loadAction(
            dynamicDataMapOf(
                stringAppDataKey("name") mapTo "Javier",
                intAppDataKey("age") mapTo 37,
            )
        )
    ),
)

onTileRequest() 受到這項動作觸發時,您可以從 requestParams.currentState.stateMap 讀取更新的資料。這對於直接修改資訊方塊資料的互動操作很有幫助,例如增加計數器或切換設定。

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {

    // When triggered by loadAction(), "name" will be "Javier", and "age" will
    // be 37.
    with(requestParams.currentState.stateMap) {
        val name = this[stringAppDataKey("name")]
        val age = this[intAppDataKey("age")]
    }

    // ...
}