在不方便轻触屏幕时,可通过手腕手势快速地与应用进行单手互动。
例如,用户可以用一只手拿着一杯水,用另一只手滚动浏览通知。手腕手势的其他用例包括:
- 在一款慢跑应用中,浏览垂直屏幕,查看所跑的步数、经过的时间以及当前的步速
- 在旅行应用中,滚动浏览航班和登机口信息
- 在新闻应用中,滚动浏览报道
如需查看手表上的手腕手势,请通过依次选择设置 > 高级功能 > 手势 > 手腕手势开启,确认已开启手势。然后选择启动教程,学完手表上的手势教程。
注意:晃动手腕是系统级的返回或撤消手势,不适用于应用自定义的操作。
如本指南所述,您可以通过以下方式使用手腕手势:
每个手腕手势都将映射到 KeyEvent
类中的 int
常量,如下表所示:
手势 | KeyEvent | 说明 |
---|---|---|
向外翻动手腕 |
KEYCODE_NAVIGATE_NEXT
|
此键码用于转到下一项。 |
向内翻动手腕 |
KEYCODE_NAVIGATE_PREVIOUS
|
此键码用于转到上一项。 |
使用曲线布局支持手腕手势
WearableRecyclerView
类为列表提供一个曲线布局,并自动支持手腕手势。该类针对视图具有焦点时做出的手腕手势预定义了操作。如需了解如何使用 WearableRecyclerView
类,请参阅在 Wear OS 上创建列表。另请参阅本指南的最佳做法部分。
注意:在穿戴式设备支持库中,WearableRecyclerView
类取代了一个与其类似且已废弃的类。
即使使用 WearableRecyclerView
,您可能也要使用 KeyEvent
类中的常量。可通过创建 WearableRecyclerView
的子类和重新实现 onKeyDown()
回调来替换预定义的操作。此行为可通过使用 setEnableGestureNavigation(false)
完全停用。如需了解详情,请参阅处理键盘操作。
直接使用按键事件
您可以使用
WearableRecyclerView
之外的按键事件触发新操作,以响应手势事件。重要的是,当设备处于活动模式时,系统会识别这些手势事件,并且这些事件的传递方式与所有按键事件相同。
就像其他任何按键事件一样,与实现
KeyEvent.Callback
的用户互动(如 View
或 Activity
)相关的类可监听与手腕手势相关的按键事件。Android 框架使用按键事件调用具有焦点的 View
或 Activity
。对于手势,在做出手势时调用 onKeyDown()
方法回调。
例如,应用可以替换实现 KeyEvent.Callback
的 View
或 Activity
中的预定义操作,如下所示:
Kotlin
class GesturesActivity : Activity() { /* KeyEvent.Callback */ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_NAVIGATE_NEXT -> // Do something that advances a user View to the next item in an ordered list. moveToNextItem() KeyEvent.KEYCODE_NAVIGATE_PREVIOUS -> // Do something that advances a user View to the previous item in an ordered list. moveToPreviousItem() else -> { // If you did not handle it, let it be handled by the next possible element as determined // by the Activity. super.onKeyDown(keyCode, event) } } } /** Shows the next item in the custom list. */ private fun moveToNextItem(): Boolean { ... // Return true if handled successfully, otherwise return false. return false } /** Shows the previous item in the custom list. */ private fun moveToPreviousItem(): Boolean { ... // Return true if handled successfully, otherwise return false. return false } }
Java
public final class GesturesActivity extends Activity { @Override /* KeyEvent.Callback */ public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_NAVIGATE_NEXT: // Do something that advances a user View to the next item in an ordered list. return moveToNextItem(); case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS: // Do something that advances a user View to the previous item in an ordered list. return moveToPreviousItem(); } // If you did not handle it, let it be handled by the next possible element as determined by the Activity. return super.onKeyDown(keyCode, event); } /** Shows the next item in the custom list. */ private boolean moveToNextItem() { boolean handled = false; ... // Return true if handled successfully, otherwise return false. return handled; } /** Shows the previous item in the custom list. */ private boolean moveToPreviousItem() { boolean handled = false; ... // Return true if handled successfully, otherwise return false. return handled; } }
最佳实践
- 查看
KeyEvent
和KeyEvent.Callback
页面,了解如何将按键事件传递到您的View
和Activity
。 - 保持一致的方向功能可见性:使用“向外翻动手腕”手势可转到下一项,使用“向内翻动手腕”手势可转到上一项
- 为手势提供对等的轻触功能。
- 提供视觉反馈。
- 不要使用键码实现与系统其他部分的常理背道而驰的功能。例如,不要使用
KEYCODE_NAVIGATE_NEXT
取消操作,也不要使用翻动姿势导航左-右轴。 - 不要拦截不属于界面的元素(例如,在屏幕之外或部分被遮盖的视图)上的按键事件。这与其他任何按键事件都一样。
- 不要将重复的翻动手势重新解释为您自己的新手势。它可能与系统的“晃动手腕”手势冲突。
如需让视图接收手势键事件,该视图必须具有焦点;请参阅
View.setFocusable()
。由于手势被视为按键事件,因此它们会触发一个转换过程,让系统退出“轻触模式”,这可能会引发意外行为。由于用户可能会交替使用轻触和手势,所以可能需要使用
View::setFocusableInTouchmode()
方法。在某些情况下,可能还需要使用setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS)
,这样一来,当从其他模式改为“轻触模式”或从“轻触模式”改为其他模式后焦点发生变化时,您的目标视图会获得焦点。- 谨慎使用
requestFocus()
和clearFocus()
:- 调用
requestFocus()
时,请确保视图适合具有焦点。如果该视图在屏幕之外或被另一个视图遮盖,那么当手势触发回调时,可能会出现意外情况。 clearFocus()
方法将启动焦点搜索,以查找另一个合适的视图。根据视图层次结构,此搜索可能需要比较复杂的计算。它最后还可能会将焦点分配给您不希望其接收焦点的视图。
- 调用
首先将按键事件传递到视图层次结构中具有焦点的视图。如果聚焦的视图不处理该事件(即,返回
false
),那么即使父视图可以接收焦点并具有KeyListener
,系统也不会将该事件传递到父视图,而是将该事件传递到容纳具有焦点的视图层次结构的当前 activity。因此,可能需要在更高的级别捕捉所有事件,然后将相关代码向下传递。或者,您也可以创建 activity 的子类并替换
dispatchKeyEvent(KeyEvent event)
方法,以在必要时拦截相应按键,或对其进行处理(如果未在较低层对其进行处理)。