在 Wear 上使用手腕手勢

在不方便觸控螢幕時,手腕手勢可讓您與應用程式進行快速的單手互動。

舉例來說,使用者可以一手拿著水杯,一手捲動畫面來查看通知。手腕手勢的其他用途包括:

  • 在慢跑應用程式中,透過垂直畫面查看跑步步數、經過時間和當前配速
  • 在旅遊應用程式中,捲動畫面查看航班和登機門資訊
  • 在新聞應用程式中,捲動畫面來瀏覽文章

如要查看手錶裝置上的手腕手勢,請依序點選「設定」>「進階功能」>「手勢」>「開啟手腕手勢」,確認手勢功能已開啟。接著,選取「啟動教學課程」,在手錶上完成手勢教學課程。

注意:搖動手腕是整個系統級別的返回或復原手勢,不適用於應用程式的自訂動作。

如以下指南所述,您可以透過以下方式使用手腕手勢:

每個手腕手勢都會對應到 KeyEvent 類別的 int 常數,如下表所示:

手勢 主要事件 說明
將手腕向外甩 KEYCODE_NAVIGATE_NEXT 這組按鍵碼會前往下一個項目。
將手腕向內甩 KEYCODE_NAVIGATE_PREVIOUS 這組按鍵碼會前往上一個項目。

使用曲線版面配置以支援手腕手勢

WearableRecyclerView 類別會提供清單用的「曲線版面配置」,並自動支援手腕手勢。當檢視區塊含有焦點時,該類別有預先定義的手腕手勢動作。如要進一步瞭解如何使用 WearableRecyclerView 類別,請參閱「在 Wear OS 建立清單」。另請參閱本指南的最佳做法一節。

注意:WearableRecyclerView 類別會取代穿戴式裝置支援資料庫中類似的已淘汰類別。

即使您使用 WearableRecyclerView,也可能需要使用 KeyEvent 類別中的常數。您可以對 WearableRecyclerView 建立子類別,並重新導入 onKeyDown() 回呼,藉此覆寫預先定義的動作。您可以使用 setEnableGestureNavigation(false) 完全停用該行為。 詳情請參閱「處理鍵盤動作」一文。

直接使用按鍵事件

您可以在 WearableRecyclerView 之外使用按鍵事件,以觸發回應手勢事件的新動作。重要的是,當裝置處於正常模式時,系統會辨識這些手勢事件,並以與所有按鍵事件相同的方式傳遞。

就像其他任何按鍵事件一樣,實作 KeyEvent.Callback 且與使用者互動相關的類別 (例如 ViewActivity),可以監聽與手腕手勢相關的按鍵事件。Android 架構會呼叫含有焦點的按鍵事件的 ViewActivity。如果是手勢,則會在做出手勢動作時呼叫 onKeyDown() 方法回呼。

舉例來說,應用程式可以覆寫實作 KeyEvent.CallbackViewActivity 中的預先定義動作,如下所示:

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 頁面,將按鍵事件傳送至您的 ViewActivity
  • 使用一致的方向功能提示:使用「手腕向外轉」手勢可前往下一項,使用「手腕向內轉」手勢可前往上一項。
  • 使用與手勢對應的觸控功能。
  • 提供視覺化回饋。
  • 請勿使用按鍵程式碼對系統其他部分實作反直覺的功能。例如,請勿使用 KEYCODE_NAVIGATE_NEXT 取消動作,或用轉動手腕手勢移動左右軸。
  • 請不要攔截不屬於使用者介面的元素上的按鍵事件,例如在畫面外或部分遭遮擋的檢視區塊。這與其他任何按鍵事件都相同。
  • 請不要將重複的轉動手腕手勢重新解讀成自己的新手勢。這可能會與系統的「搖動手腕」手勢發生衝突。
  • 檢視區塊必須具有 ,才能接收手勢按鍵事件。請參閱 View.setFocusable()

    系統會將手勢視為按鍵事件,因此會觸發轉換程序使系統退出「觸控模式」,這可能會發生無預期的狀況。由於使用者可能會同時使用觸控和手勢,因此可能需要使用 View::setFocusableInTouchmode() 方法。在某些情況下,可能也需要使用 setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS),如此一來,當「觸控模式」變更為其他模式時,或由其他模式變更為觸控模式時,目標檢視區塊就會獲得焦點。

  • 請謹慎使用 requestFocus()clearFocus()
    • 呼叫 requestFocus() 時,請確保檢視區塊適合擁有焦點。如果檢視區塊位於螢幕畫面之外,或遭其他檢視區塊遮擋,當手勢觸發回呼,就可能會發生意外狀況。
    • clearFocus() 方法會啟動焦點搜尋,以尋找其他適合的檢視區塊。視檢視區塊階層而定,這項搜尋可能需要較複雜的計算。但最終也會將焦點指派給您不希望其接收焦點的檢視區塊。
  • 系統會先將按鍵事件傳送至檢視區塊階層中具有焦點的檢視區塊。如果聚焦的檢視區塊無法處理該事件 (也就是回傳 false),該事件就不會傳送至父項檢視區塊,即使該檢視區塊可以接收焦點且具有 KeyListener 也一樣。相反地,該事件會傳送至當前容納擁有焦點的檢視區塊階層的活動。

    因此,您可能必須在較高層級擷取所有事件,然後再將相關程式碼向下傳送。或者,您也可以對活動建立子類別,並且視需要覆寫 dispatchKeyEvent(KeyEvent event) 方法,以便攔截相應按鍵,如果先前未在較低層級對活動進行處理,也可以進行這項作業。