從 Wear OS 7 (API 級別 37) 開始,單手勢架構和 Compose for Wear OS 的 API,可讓使用者與應用程式互動時不必觸控螢幕。
這項架構最初支援 Pixel Watch 裝置 (Pixel Watch 3 和後續機型),但現在所有原始設備製造商都能使用。採用這項 API 後,隨著硬體支援範圍擴大,應用程式的手勢支援功能也會自動在整個生態系統中擴展。
為協助使用者探索可用手勢,同時避免使用者介面過於雜亂,Wear OS 架構提供動畫手勢指標。這些視覺提示會標示可執行手勢的位置,而系統會根據使用者偏好設定,自動管理提示的顯示頻率和靜音頻率。
支援的手勢和動作
Wear OS 手勢架構支援兩種手勢類型:
- 主要動作 (雙指捏合):對應螢幕上的主要動作,例如接聽電話或切換媒體播放。
- 取消動作 (轉動手腕):對應向後導覽、關閉對話方塊或取消提示。
在 Compose 中設定手勢
雖然單手操作手勢 API 可以提升 UI,但請務必注意,部分硬體和原始設備製造商不支援這些手勢。如果 API 偵測到應用程式在不支援的裝置上執行,程式庫會自動執行空作業,不會影響標準觸控互動。
與標準 Compose 行為相同,您可以使用修飾符,在 UI 元素上啟用單手手勢。您可以根據要執行的動作 (主要或關閉) 設定應用程式的手勢,並使用 gestureId 配合系統層級的使用者偏好設定,例如提示顯示步頻和頻率靜音。您可以建立 OneHandedGestureConfiguration 物件來表示這項設定,建議使用 rememberOneHandedGestureConfiguration 函式建立該物件。您也可以在 OneHandedGestureConfiguration 中提供手勢優先順序。
rememberOneHandedGestureConfiguration 函式會追蹤重組作業中的使用者互動記錄,但不會公開應用程式狀態。應用程式建立設定後,應將設定傳遞至互動式可組合函式中的 Modifier.oneHandedGesture。
為協助使用者探索可用的手勢,程式庫提供 OneHandedGestureClickIndicator 方法。這個方法會做為包裝函式,取代基礎內容,向使用者指出可執行的手勢動作。
互動式元件
如要在按鈕等互動式控制項上啟用手勢,請建立指定 OneHandedGestureAction.Primary 的設定,並套用 oneHandedGesture 修飾符。將相同的 MutableInteractionSource 傳遞至控制項和修飾符,手勢事件就會在控制項上發出視覺按壓回饋。
如要啟用手勢指標,請建立並記錄 OneHandedGestureClickIndicatorState 的例項。接著,在 oneHandedGesture 修飾符提供的 onGestureAvailable 回呼中呼叫 showIndicator,即可觸發視覺回饋,向系統發出發生指標事件的信號。呼叫後,元件會暫時以手勢動畫取代正常內容。
var isPlaying by remember { mutableStateOf(false) } val onClick = { isPlaying = !isPlaying } val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary ) val indicatorState = remember { OneHandedGestureClickIndicatorState() } val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } Button( onClick = onClick, interactionSource = interactionSource, modifier = Modifier .fillMaxWidth() .oneHandedGesture( gestureConfiguration = gestureConfig, interactionSource = interactionSource, onGestureLabel = if (isPlaying) "pause" else "play", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = onClick ) ) { OneHandedGestureClickIndicator( gestureConfiguration = gestureConfig, state = indicatorState ) { Text(if (isPlaying) "Pause" else "Play", modifier = Modifier.fillMaxWidth()) } }
可捲動的容器
如果是可捲動的畫面或清單,請建立指定 OneHandedGestureAction.Primary 的設定,然後將 oneHandedGesture 修飾符套用至容器,並呼叫捲動輔助程式 (例如 scrollDown)。
如要為捲動動作提供視覺回饋,可以使用 OneHandedGestureScrollIndicator。這個元件可做為標準捲動指標,顯示捲動位置,但也可以指出使用者可進行捲動手勢。這項指標通常會傳遞至 ScreenScaffold 的 scrollIndicator slot,並與可捲動容器 (例如 TransformingLazyColumn) 的狀態配對。此外,它也會觀察 OneHandedGestureScrollIndicatorState,以便管理視覺轉換。
如要觸發視覺回饋,請在這個狀態下呼叫 showIndicator,通常是在 oneHandedGesture 修飾符的 onGestureAvailable 回呼內。觸發後,指標會暫時以手勢動畫序列取代標準視覺狀態,提醒使用者。
val scrollState = rememberTransformingLazyColumnState() val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary, priority = OneHandedGesturePriority.Scrollable ) val indicatorState = remember(gestureConfig) { OneHandedGestureScrollIndicatorState() } val coroutineScope = rememberCoroutineScope() ScreenScaffold( scrollState = scrollState, scrollIndicator = { OneHandedGestureScrollIndicator( gestureConfiguration = gestureConfig, indicatorState = indicatorState, scrollState = scrollState, modifier = Modifier.align(Alignment.CenterEnd) ) } ) { contentPadding -> TransformingLazyColumn( state = scrollState, contentPadding = contentPadding, modifier = Modifier .fillMaxSize() .oneHandedGesture( gestureConfiguration = gestureConfig, onGestureLabel = "scroll", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) } ) ) { items(10) { index -> Text("Item $index", modifier = Modifier.padding(8.dp)) } } }
結合多個手勢
如要使用相同的基本動作設定捲動和點擊手勢,請在 OneHandedGestureConfiguration 物件中新增 gesturePriority:
OneHandedGesturePriority.Clickable(最高): 指派給互動式控制項 (例如類型為Button或Card的控制項),以便在螢幕上顯示時擷取手勢。OneHandedGesturePriority.Scrollable(中): 指派給可捲動或可分頁的容器,讓容器讓給可點選的子項,但沒有可點選的控制項時則會捲動。OneHandedGesturePriority.Unspecified(最低): 未指派優先順序。這是沒有設定priority的手勢預設值。
明確在內部按鈕上設定 priority = OneHandedGesturePriority.Clickable,並在父項清單上設定 priority = OneHandedGesturePriority.Scrollable,系統即可顯示這項手勢優先行為。使用者以單手手勢觸發主要動作時,系統會先向下捲動清單,直到按鈕顯示為止。然後擷取按鈕的點擊動作。
使用 ADB 測試手勢並進行偵錯
您可以在實體裝置或模擬器上測試單手勢,不必實際移動手腕,只要使用 Android Debug Bridge (adb) 和 IWearGestureService 系統服務即可。
啟用手勢模擬
- 確認 Wear OS 裝置搭載 Wear OS 7 (API 級別 37) 以上版本。
- 如果是在未戴在手腕上或未接上充電器的實體裝置上測試,請覆寫離身感應器狀態,讓裝置保持啟用狀態:
adb shell cmd sensorservice set-off-body-state 0
使用 ADB 觸發手勢事件
如要模擬「雙指撥動」手勢 (即 Pixel Watch 上的 Primary 動作),請執行下列 ADB Shell 指令:
adb shell cmd IWearGestureService gesture 1
如要模擬「手腕轉動」手勢 (即 Pixel Watch 上的 Dismiss 動作),請執行下列 ADB Shell 指令:
adb shell cmd IWearGestureService gesture 2
重設手勢提示追蹤
系統會追蹤使用者互動記錄,並根據全域節奏設定 (例如「一律」或「每天」) 顯示懸浮手勢提示。偵錯應用程式的手勢指標時,請重設這項追蹤記錄,讓系統再次顯示套件的提示:
adb shell cmd IWearGestureService hint clear <your_package_name>
測試完成後,如要重設離身感應器狀態,請按照下列步驟操作:
adb shell cmd sensorservice reset-off-body-state
其他資源
如需單手手勢的使用時機和場合設計指南,請參閱「單手手勢」。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 單手手勢設計指南