欢迎参加我们将于 6 月 3 日举行的 #Android11:Beta 版发布会

Wear 上的旋转输入

某些 Wear OS 设备支持旋转输入,如侧面旋钮 (RSB)。当用户旋转旋钮时,您的应用的当前视图应向上或向下滚动。

如果您在应用中使用 ScrollViewListViewHorizontalScrollViewWearableRecyclerView,那么您的应用视图将默认支持旋转输入。如果您使用上述视图以外的自定义视图,或者您想手动处理旋转输入事件,请参阅添加自定义旋转输入滚动

请参阅以下相关资源:

焦点最佳做法

为响应旋转输入事件,您的滚动视图必须获得焦点。大多数情况下,滚动视图会自动获得焦点。在您创建 Activity 后,您的滚动视图会立即获得焦点。不过,在某些情况下,您需要手动处理应用视图的焦点,例如:

  • 如果您的可滚动视图会在 Activity.onCreate() 之后附加(例如,您要等到网络请求完成后再构建界面),那么您必须在附加该视图之后调用 requestFocus
  • 如果您的可滚动视图最初为 INVISIBLEGONE,则在将其设置为 VISIBLE 时必须调用 requestFocus
  • 如果您的 Activity 包含多个可滚动视图(例如,如果您使用嵌套滚动),那么您需要从中选择一个来获得焦点(通常通过 <requestFocus /> 标记来设置)。RSB 滚动目前不支持嵌套滚动。
  • 如果您的界面包含其他某种在用户与它交互时会窃取焦点的视图(这种情况很少见;最常见的示例为 InputText),则您需要为用户提供某种方式,让他们能够在可滚动视图失去焦点后使其重新获得焦点。这通常可通过侦听可滚动视图上的点按操作并在响应中调用 requestFocus 来实现。

添加自定义旋转输入滚动

如果您的可滚动视图本身不支持旋转输入滚动,或者您想要执行一些不同于滚动的操作来响应旋转输入事件(例如放大/缩小、旋转表盘等),那么您可以使用穿戴式设备支持库中的 RotaryEncoder 方法。

以下代码段说明了如何使用 RotaryEncoder 在应用视图中添加自定义滚动:

Kotlin

    myView.setOnGenericMotionListener(View.OnGenericMotionListener { v, ev ->
        if (ev.action == MotionEvent.ACTION_SCROLL && RotaryEncoder.isFromRotaryEncoder(ev)) {
            // Don't forget the negation here
            val delta = -RotaryEncoder.getRotaryAxisValue(ev) *
                    RotaryEncoder.getScaledScrollFactor(context)

            // Swap these axes if you want to do horizontal scrolling instead
            v.scrollBy(0, Math.round(delta))

            return@OnGenericMotionListener true
        }

        false
    })
    

Java

    myView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
        @Override
        public boolean onGenericMotion(View v, MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_SCROLL && RotaryEncoder.isFromRotaryEncoder(ev)) {
                // Don't forget the negation here
                float delta = -RotaryEncoder.getRotaryAxisValue(ev) * RotaryEncoder.getScaledScrollFactor(
                getContext());

                // Swap these axes if you want to do horizontal scrolling instead
                v.scrollBy(0, Math.round(delta));

                return true;
            }

            return false;
        }
    });
    

在模拟器上测试旋转输入按钮

您可以使用 Android 模拟器来模拟 Wear 设备上的旋转输入滚动。您可以在运行项目时在模拟器上启动 Wear 应用,也可以将 APK 文件拖动到模拟器上以安装 APK。

要在模拟器上测试旋转输入,请执行以下操作:

  1. SDK 管理器中,使用 SDK 工具标签获取 Android 模拟器 26.0.3 或更高版本。
  2. 使用 API 25 创建一个 AVD(Android 虚拟设备)。

    在 Studio 中,依次选择 Tools > Android > AVD Manager。使用 API 25 创建一个新的 Wear 设备

  3. 在 Android Studio 中运行模拟器
  4. 尝试执行旋转输入滚动。

    点击溢出按钮(模拟器工具栏底部的三个点)。点击新窗口中的 Rotary input 标签以打开旋转输入界面。

以下视频展示了模拟器中的旋转输入。

焦点行为提示

  • 如果为视图设置了 setFocusableInTouchMode(true),则表示该视图可获得焦点。默认情况下,这仅适用于可滚动视图(例如,ScrollView)和 InputText
  • 默认情况下,点按某个视图不会使其获得焦点(即使该视图可获得焦点)。要实现此行为,视图必须监听点按事件,并且您需要手动调用 View.requestFocus()
  • Activity 在创建后,会立即自动将焦点赋予它在自己的视图层次结构中找到的第一个可获得焦点的视图。如果您的 Activity 中有多个可获得焦点的视图,那么 Activity 自动选择的视图可能不是您想要的视图。您可以使用 <requestFocus /> 标记(或在 Activity.onResume 中手动调用 View.requestFocus)为其他视图赋予焦点。
  • 如果在创建 Activity 后附加或取消隐藏某个可获得焦点的视图,则该视图将不会自动获得焦点,即使当前没有视图获得焦点也是如此。在这种情况下,您需要手动调用 View.requestFocus
  • 系统只会将旋转输入事件发送给获得焦点的视图。这些事件不会在视图层次结构中向上传递。当且仅当没有视图获得焦点或获得焦点的视图从 View.onGenericMotionEvent 返回 false 时,系统才会将事件发送给 Activity.onGenericMotionEvent