로터리 입력은 시계에서 회전하는 부분의 입력을 의미합니다. 평균적으로 사용자가 시계와 상호작용하는 데는 몇 초밖에 걸리지 않습니다. 로터리 입력을 사용하면 사용자가 다양한 작업을 빠르게 완료할 수 있어 사용자 환경을 개선할 수 있습니다.
대부분의 시계에서 로터리 입력의 세 가지 기본 소스에는 회전 측면 버튼(RSB)과 물리적 베젤 또는 터치 베젤(화면 주변의 원형 터치 영역)이 있습니다. 예상되는 동작은 입력 유형에 따라 다를 수 있지만 모든 필수 상호작용에는 로터리 입력을 지원해야 합니다.
스크롤
대부분의 사용자는 앱이 스크롤 동작을 지원할 것으로 기대합니다. 콘텐츠가 화면에서 스크롤될 때 로터리 상호작용에 대한 응답으로 시각적 피드백을 사용자에게 제공합니다. 시각적 피드백에는 세로 스크롤을 위한 위치 표시기 또는 페이지 표시기가 포함될 수 있습니다.
ScalingLazyColumn
및 Picker
는 이러한 구성요소를 Scaffold
내에 배치해야 하는 경우 기본적으로 스크롤 동작을 지원합니다. Scaffold
는 Wear OS 앱의 기본 레이아웃 구조를 제공하며 이미 스크롤 표시기를 위한 슬롯이 있습니다. 스크롤 진행률을 표시하려면 다음 코드 스니펫과 같이 목록 상태 객체를 기반으로 위치 표시기를 만듭니다.
val listState = rememberScalingLazyListState() Scaffold( positionIndicator = { PositionIndicator(scalingLazyListState = listState) } ) { // ... }
다음 코드 스니펫과 같이 ScalingLazyColumnDefaults.snapFlingBehavior
를 사용하여 ScalingLazyColumn
의 스냅 동작을 구성할 수 있습니다.
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(),
) { ... }
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 포커스 동작 변경
- Jetpack Compose로 키보드, 마우스, 트랙패드, 스타일러스 지원 추가
- Wear OS용 Compose Codelab