Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Một số thiết bị Wear OS có nút xoay ở cạnh. Khi người dùng vặn nút, nút này sẽ cuộn lên hoặc xuống chế độ xem hiện tại của ứng dụng. Dạng nhập dữ liệu đầu vào này được gọi là phương thức nhập dữ liệu xoay.
Lưu ý: Hướng dẫn này chủ yếu đề cập đến cách xử lý phương thức nhập dữ liệu xoay qua giao diện người dùng dựa trên Thành phần hiển thị. Để biết thêm thông tin về cách xử lý phương thức nhập dữ liệu xoay qua Compose cho Wear OS, hãy xem phần Phương thức nhập dữ liệu xoay trên Compose.
Nhiều vùng chứa có thể cuộn, chẳng hạn như ScrollView, ListView, HorizontalScrollView và WearableRecyclerView, hỗ trợ phương thức nhập dữ liệu xoay nếu chúng có tiêu điểm mà không cần phải có đoạn mã cụ thể cho Wear OS.
Có tiêu điểm là một điều kiện tiên quyết quan trọng vì trên Android 9 (API cấp 28) trở lên, các chế độ xem hoàn toàn không nhận được tiêu điểm.
Các phương pháp hay nhất về tiêu điểm
Để phản hồi các sự kiện nhập dữ liệu xoay, vùng chứa có thể cuộn phải có tiêu điểm.
Các sự kiện nhập dữ liệu xoay không làm bật lên hệ phân cấp chế độ xem. Nếu không có chế độ xem tập trung hoặc nếu chế độ xem tập trung trả về false qua View.onGenericMotionEvent() thì sự kiện sẽ được gửi đến Activity.onGenericMotionEvent().
Dưới đây là các phương pháp hay nhất để phản hồi sự kiện nhập dữ liệu xoay:
Hãy lưu ý rằng, theo mặc định, việc chạy một hoạt động hoặc thậm chí là nhấn vào một chế độ xem không tạo ra được tiêu điểm, ngay cả khi hoạt động đó có thể là tâm điểm. Để lấy tiêu điểm cho chế độ xem của bạn, chế độ xem phải sử dụng thẻ <requestFocus /> hoặc gọi View.requestFocus() theo cách thủ công.
Đánh dấu các chế độ xem cuộn tuỳ chỉnh dưới dạng thành phần có thể lấy tiêu điểm bằng cách sử dụng cả android:focusable="true" và android:focusableInTouchMode="true".
Nếu chế độ xem cuộn được đính kèm sau Activity.onCreate() (ví dụ: đợi một yêu cầu mạng kết thúc trước khi xây dựng giao diện người dùng), hãy gọi requestFocus() sau khi đính kèm chế độ xem cuộn này.
Nếu chế độ xem cuộn ban đầu là INVISIBLE hoặc GONE, hãy gọi requestFocus() khi bạn đặt thành VISIBLE.
Nếu hoạt động có nhiều chế độ xem cuộn, hãy chọn một thành phần để tập trung (lấy tiêu điểm) thông qua thẻ <requestFocus />. Tính năng cuộn lồng nhau không được nút xoay bên hông hỗ trợ.
Nếu giao diện người dùng của bạn chứa một số chế độ xem khác lấy tiêu điểm khi người dùng tương tác (ví dụ: InputText), hãy cung cấp cho người dùng cách để khôi phục tiêu điểm về chế độ xem cuộn nếu chế độ xem này bị mất tiêu điểm bằng cách nghe thao tác nhấn vào chế độ xem cuộn và gọi requestFocus() để phản hồi.
Hành vi xoay tuỳ chỉnh
Nếu chế độ xem cuộn không hỗ trợ thao tác cuộn phương thức nhập dữ liệu xoay, hoặc nếu bạn muốn sử dụng phương thức nhập dữ liệu xoay cho thao tác khác thay vì cuộn (ví dụ: phóng to/thu nhỏ hoặc quay số), bạn có thể tự xử lý các sự kiện cuộn. Hãy nhớ đảm bảo chế độ xem của bạn lấy được tiêu điểm. Nếu không, các sự kiện sẽ không diễn ra.
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;}});
Thử nghiệm bằng trình mô phỏng
Sử dụng Trình mô phỏng Android để mô phỏng thao tác cuộn phương thức nhập dữ liệu xoay trên thiết bị Wear. Mở ứng dụng Wear trên trình mô phỏng để chạy dự án hoặc kéo tệp APK vào trình mô phỏng để cài đặt.
Cách kiểm thử phương thức nhập dữ liệu xoay trên trình mô phỏng:
Từ Trình quản lý SDK, hãy sử dụng thẻ Bộ công cụ SDK để tải Trình mô phỏng Android 26.0.3 trở lên.
Trong Android Studio, hãy chọn Tools >
Android > AVD Manager (Công cụ > Android > Trình quản lý thiết bị ảo Android).
Tạo thiết bị Wear mới bằng API 25
trở lên.
Nhấp vào nút ba dấu chấm của trình đơn mục bổ sung ở cuối thanh công cụ của trình mô phỏng. Nhấp vào thẻ Phương thức nhập dữ liệu xoay trong cửa sổ mới để mở giao diện nhập dữ liệu xoay và thử cuộn phương thức nhập dữ liệu xoay.
Video sau đây cho thấy phương thức nhập dữ liệu xoay trong trình mô phỏng:
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-26 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 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:"]]