使用 Compose 進行旋轉輸入

旋轉輸入是指轉動或旋轉手錶零件來輸入內容。使用者與手錶互動的時間平均只有幾秒鐘,因此建議您使用旋轉輸入機制,讓使用者快速完成各項工作,打造更優質的使用者體驗。

多數手錶上的三個主要旋轉輸入來源,包括側邊旋轉按鈕 (RSB)、實體邊框或觸控邊框,後者是指螢幕周圍的圓形觸控區。即使預期的行為可能因輸入類型而有所不同,請務必為所有重要互動方式支援旋轉輸入。

捲動

大多數使用者會預期應用程式支援捲動手勢。使用者在畫面上捲動內容時,請提供回應旋轉互動動作的視覺回饋。視覺回饋可包括用於垂直捲動的位置指標頁面指標

ScalingLazyColumnPicker 預設會支援捲動手勢,只要您需要將這些元件放入 Scaffold 即可。Scaffold 可為 Wear OS 應用程式提供基本的版面配置結構,且已有捲動指標專用的版位。如要顯示捲動進度,請根據清單狀態物件建立位置指標,如以下程式碼片段所示:

val listState = rememberScalingLazyListState() Scaffold(     positionIndicator = {         PositionIndicator(scalingLazyListState = listState)     } ) {     // ... }

您可以使用 ScalingLazyColumnDefaults.snapFlingBehaviorScalingLazyColumn 設定固定行為,如以下程式碼片段所示:

val listState = rememberScalingLazyListState() Scaffold(     positionIndicator = {         PositionIndicator(scalingLazyListState = listState)     } ) {      val state = rememberScalingLazyListState()     ScalingLazyColumn(         modifier = Modifier.fillMaxWidth(),         state = state,         flingBehavior = ScalingLazyColumnDefaults.snapFlingBehavior(state = state)     ) {         // Content goes here         // ...     } }

自訂操作

您也可以建立自訂動作,對應用程式中的旋轉輸入內容做出回應。例如使用旋轉輸入放大及縮小畫面,或控制媒體應用程式中的音量。

如果元件原本不支援捲動事件 (例如音量控制),您可以自行處理捲動事件。

// VolumeScreen.kt  val focusRequester: FocusRequester = remember { FocusRequester() }  Column(     modifier = Modifier         .fillMaxSize()         .onRotaryScrollEvent {             // handle rotary scroll events             true         }         .focusRequester(focusRequester)         .focusable(), ) { ... } 

建立透過檢視模型管理的自訂狀態,以及用來處理旋轉捲動事件的自訂回呼。

// VolumeViewModel.kt  object VolumeRange(     public val max: Int = 10     public val min: Int = 0 )  val volumeState: MutableStateFlow<Int> = ...  fun onVolumeChangeByScroll(pixels: Float) {     volumeState.value = when {         pixels > 0 -> min (volumeState.value + 1, VolumeRange.max)         pixels < 0 -> max (volumeState.value - 1, VolumeRange.min)     } } 

為求簡單起見,上方範例使用了像素值 (如果實際使用可能會導致靈敏度過高)。

在接收到事件後使用回呼,如以下程式碼片段所示。

val focusRequester: FocusRequester = remember { FocusRequester() } val volumeState by volumeViewModel.volumeState.collectAsState()  Column(     modifier = Modifier         .fillMaxSize()         .onRotaryScrollEvent {             volumeViewModel                 .onVolumeChangeByScroll(it.verticalScrollPixels)             true         }         .focusRequester(focusRequester)         .focusable(), ) { ... }