활동에 스크롤 가능한 뷰가 여러 개 있다면 <requestFocus /> 태그를 통해 포커스를 둘 뷰를 선택합니다. 중첩 스크롤은 측면 회전 버튼에서 지원되지 않습니다.
사용자가 UI와 상호작용할 때 포커스를 가져가는 다른 뷰가 UI에 포함되어 있다면(예: InputText) 스크롤 가능한 뷰가 포커스를 잃을 경우 스크롤 가능한 뷰에서 탭을 리슨하고 응답으로 requestFocus()를 호출하는 방식으로 포커스를 복원하는 방법을 사용자에게 제공합니다.
맞춤 회전 동작
스크롤 가능한 뷰가 기본적으로 로터리 입력 스크롤을 지원하지 않거나 스크롤 이외의 용도(예: 확대/축소 또는 다이얼 돌리기)로 로터리 입력을 사용하려는 경우 스크롤 이벤트를 직접 처리하면 됩니다. 뷰가 포커스를 받도록 해야 합니다. 그러지 않으면 이벤트가 발생하지 않습니다.
myView.setOnGenericMotionListener{v,ev->
if(ev.action==MotionEvent.ACTION_SCROLL&&
ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)){// Don't forget the negation herevaldelta=-ev.getAxisValue(MotionEventCompat.AXIS_SCROLL)*ViewConfigurationCompat.getScaledVerticalScrollFactor(ViewConfiguration.get(context),context)// Swap these axes to scroll horizontally insteadv.scrollBy(0,delta.roundToInt())true}else{false}}
Java
myView.setOnGenericMotionListener(newView.OnGenericMotionListener(){@OverridepublicbooleanonGenericMotion(Viewv,MotionEventev){if(ev.getAction()==MotionEvent.ACTION_SCROLL&&
ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)){// Don't forget the negation herefloatdelta=-ev.getAxisValue(MotionEventCompat.AXIS_SCROLL)*ViewConfigurationCompat.getScaledVerticalScrollFactor(ViewConfiguration.get(context),context);// Swap these axes to scroll horizontally insteadv.scrollBy(0,Math.round(delta));returntrue;}returnfalse;}});
에뮬레이터를 사용하여 테스트
Android Emulator를 사용하여 Wear 기기에서 로터리 입력 스크롤을 시뮬레이션합니다. 에뮬레이터에서 Wear 앱을 실행하여 프로젝트를 실행하거나 APK 파일을 에뮬레이터로 드래그하여 설치합니다.
에뮬레이터에서 로터리 입력을 테스트하려면 다음을 따르세요.
SDK Manager의 SDK Tools 탭에서 Android Emulator 26.0.3 이상을 가져옵니다.
Android 스튜디오에서 Tools > Android > AVD Manager를 선택합니다.
API 25 이상으로 새 Wear 기기를 만듭니다.
에뮬레이터 툴바 하단에서 점 3개로 된 더보기 메뉴를 클릭합니다. 새 창에서 Rotary input 탭을 클릭하여 로터리 입력 인터페이스를 열고 로터리 입력 스크롤을 시도합니다.
다음 동영상은 에뮬레이터에서의 로터리 입력을 보여줍니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-26(UTC)
[null,null,["최종 업데이트: 2025-07-26(UTC)"],[],[],null,["# Rotary input\n\nSome Wear OS devices contain a physical *rotating side button* . When the user turns the\nbutton, it scrolls your app's current view up or down. This type of input is called\n*rotary input*.\n\n**Note:** This guide refers primarily to handling rotary input using\nView-based UIs. For more information on handling rotary input using Compose for Wear OS, see\n[Rotary input on Compose](/training/wearables/compose/rotary-input).\n\nMany scrollable containers, like\n[ScrollView](/reference/android/widget/ScrollView),\n[ListView](/reference/android/widget/ListView),\n[HorizontalScrollView](/reference/android/widget/HorizontalScrollView),\nand [WearableRecyclerView](/reference/androidx/wear/widget/WearableRecyclerView),\nsupport rotary input if they have focus without requiring any Wear\nOS-specific code.\nHaving focus is an important prerequisite, because on Android 9 (API level\n28) and higher, views don't implicitly receive focus.\n\nFocus best practices\n--------------------\n\n\nTo respond to rotary input events, a scrollable container must have focus.\nRotary input events don't bubble up the view\nhierarchy. If there is no focused view, or if the focused view returns `false` from\n[View.onGenericMotionEvent()](/reference/android/view/View#onGenericMotionEvent(android.view.MotionEvent)),\nthen the event is sent to\n[Activity.onGenericMotionEvent()](/reference/android/app/Activity#onGenericMotionEvent(android.view.MotionEvent)).\n\n\nThe following are best practices around responding to rotary input events:\n\n- Bear in mind that, by default, launching an activity or even tapping on a view does not give it focus, even if it is focusable. To give your view focus, the view must use the [<requestFocus /\u003e](/guide/topics/resources/layout-resource) tag or manually call [View.requestFocus()](/reference/android/view/View#requestFocus()).\n- Mark custom scrollable views as focusable using both `android:focusable=\"true\"` and `android:focusableInTouchMode=\"true\"`.\n- If your scrollable view is attached after [Activity.onCreate()](/reference/android/app/Activity#onCreate(android.os.Bundle))---for example, waiting for a network request to finish before building your UI, call `requestFocus()` after attaching it.\n- If your scrollable view is initially [INVISIBLE](/reference/android/view/View#INVISIBLE) or [GONE](/reference/android/view/View#GONE), call `requestFocus()` when you set it to [VISIBLE](/reference/android/view/View#VISIBLE).\n- If your activity contains multiple scrollable views, choose one to focus using the [<requestFocus /\u003e](/guide/topics/resources/layout-resource) tag. Nested scrolling is not supported with the rotating side button.\n- If your UI contains some other view that takes focus when the user interacts with it---for example, an `InputText`, give the user a way to restore focus to the scrollable view if it loses focus by listening for taps on the scrollable view and calling `requestFocus()` in response.\n\nCustom rotating behavior\n------------------------\n\nIf your scrollable view doesn't natively support rotary input scrolling, or if you want to\nuse your rotary input for something other than scrolling---such as to\nzoom in and out or to turn dials---you can handle the scroll events\nyourself. Remember to make sure your view gains focus, otherwise\nthe events will not come through.\n\nThe following code snippet shows how to use [MotionEvent](/reference/android/view/MotionEvent),\n[InputDeviceCompat](/reference/kotlin/androidx/core/view/InputDeviceCompat),\nand [ViewConfigurationCompat](/reference/androidx/core/view/ViewConfigurationCompat)\nto add custom scrolling to your view: \n\n### Kotlin\n\n```kotlin\nmyView.setOnGenericMotionListener { v, ev -\u003e\n if (ev.action == MotionEvent.ACTION_SCROLL &&\n ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)\n ) {\n // Don't forget the negation here\n val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *\n ViewConfigurationCompat.getScaledVerticalScrollFactor(\n ViewConfiguration.get(context), context\n )\n // Swap these axes to scroll horizontally instead\n v.scrollBy(0, delta.roundToInt())\n true\n } else {\n false\n }\n}\n```\n\n### Java\n\n```java\nmyView.setOnGenericMotionListener(new View.OnGenericMotionListener() {\n @Override\n public boolean onGenericMotion(View v, MotionEvent ev) {\n if (ev.getAction() == MotionEvent.ACTION_SCROLL &&\n ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)\n ) {\n // Don't forget the negation here\n float delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *\n ViewConfigurationCompat.getScaledVerticalScrollFactor(\n ViewConfiguration.get(context), context\n );\n\n // Swap these axes to scroll horizontally instead\n v.scrollBy(0, Math.round(delta));\n\n return true;\n }\n return false;\n }\n});\n```\n\nTest using an emulator\n----------------------\n\nUse the [Android Emulator](/studio/run/emulator#about) to simulate rotary input\nscrolling on a Wear device. Launch your Wear app on the emulator to run\nyour project or drag an\nAPK file onto the emulator to install it.\n\nTo test the rotary input on the emulator:\n\n1. From the [SDK manager](/tools/help/sdk-manager), use the **SDK tools** tab to get Android Emulator 26.0.3 or higher.\n2. In Android Studio, select **Tools \\\u003e\n Android \\\u003e AVD Manager** . [Create a new Wear device](/studio/run/managing-avds#createavd) with API 25 or higher.\n3. [Run the emulator from Android Studio](/studio/run/emulator#runningapp).\n4. Click the three-dot overflow menu at the bottom of the emulator toolbar. Click the **Rotary input** tab in the new window to open the rotary input interface and try rotary input scrolling.\n\nThe following video shows rotary input in the emulator:"]]