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(), ) { ... }