是時候為各式設備適配完善的輸入支持了

語言: CN / TW / HK

隨着技術進步以及跨平台應用的普及,您的 Android 應用已經不再侷限於在直板觸屏設備運行了。更豐富的交互方式使得用户能夠以更復雜的輸入方式使用您的應用。所以作為開發者,是時候考慮為各種各樣的設備提供強大的輸入支持了。本文為您準備了關於更廣泛、強大的輸入支持的分享,歡迎您閲讀。

如果您更喜歡通過視頻瞭解此內容,請 點擊此處 查看。

對於各種 Android 設備來説,輸入 (input) 是決定用户應用體驗的關鍵要素之一。開發者通常希望用户交互方式能儘可能簡單直觀,但是假如您新買了一個可摺疊設備,附贈了一款鍵盤,而您喜歡的應用卻不支持標準按鍵操作,這種體驗將非常令人沮喪。

目前許多 Android 設備內置了非觸摸輸入 (non-touch input),比如 Chromebook 鍵盤,甚至一些設備將其作為標配提供。那麼在諸如手機、可摺疊設備、平板電腦、Chromebook、支持外接顯示屏的 Chromebox、帶內置顯示器的 Chromebase、Android TV 等各種 Android 設備類型中,開發者應該如何確保不同的輸入方式適用於自己的應用。

△ 多種 Android 設備

△ 多種 Android 設備

要知道並非所有的用户都使用手機觸摸屏與您的應用交互,一部分用户可能使用的是鍵盤和觸控筆等,甚至一部分用户有 無障礙 需求。那麼每位開發者都有必要花些時間去思考,如何使應用為儘可能多的用户帶來愉快的使用體驗?

增強輸入 (Enhanced input)

△ 標準輸入方式和增強輸入方式

△ 標準輸入方式和增強輸入方式

對於每種類型的輸入設備,我們可以將應用的功能分為標準用例和增強用例兩大類:

  • 標準用例包括選擇、文本輸入、長按和右鍵點擊等這些用户所期望的功能,處理此類用例的技術實現比較簡單且在某些情況下可以自動執行。如果想要為應用提供更多獨特和增強的支持,則需要開發者多加考慮。

  • 在增強用例中,某些功能不只是有了更好,而可能是必需具備的,例如一款不支持遊戲手柄的手機遊戲和一款不支持標準複製和粘貼快捷鍵的文本編輯器,都是無法受到用户歡迎的。

在提供基礎功能外,要考慮添加獨特且能為用户提供支持的功能,這才是開發者讓自己應用真正脱穎而出的方法。例如,如下所示的 eDJing 這款應用,它添加了對鍵盤打碟和觸控板搓碟以及 MIDI DJ 控制器的支持,用户手中的手機或 Chromebook 就能夠立即搖身一變成為 DJ 工作站。

△ eDJing 應用使用場景

△ eDJing 應用使用場景

Cubasis 是一款一流的數字音頻工作站應用,它發佈了基於 Chrome OS 操作系統優化的新版本,憑藉大屏幕的優勢以及 MIDI 控制器連接 Chromebook 的便利性,不僅增強了功能,還提升了應用實用性。

△ Cubasis 應用使用場景

△ Cubasis 應用使用場景

繪圖類應用則更加註重: 藍牙和 USB 繪圖板能夠持續正常的工作,以及在 Chrome OS 操作系統中將低延遲觸控筆 API 應用到繪圖和繪畫應用中。

△ 繪圖類應用使用場景

△ 繪圖類應用使用場景

簡而言之,用户希望能在您的應用中獲得獨特、愉悦、直觀的體驗,而這種體驗由您來打造!

鍵盤輸入支持

鍵盤被內置在 Chromebook 中,或是成為用户在使用可拆卸設備、平板電腦、可摺疊設備和電視過程中日常體驗的一部分。好消息是大多數基本鍵盤輸入通常可以直接使用,除非您正致力於構建自己的屏幕鍵盤或從頭開始編寫自己的文本輸入視圖。

發送鍵支持 (KEYCODE_ENTER)

開發者需要在標準的 EditText 視圖中為 Enter 鍵創建一個新行。如果您的應用中有聊天功能、反饋表單、簡報註冊或任何需要發送文本的功能,那麼默認的換行行為肯定不是您所期望的,不用擔心的是您所預期的發送功能很容易實現。

△ 聊天發送文本

△ 聊天發送文本

開發者需要在標準的 EditText 視圖中為 Enter 鍵創建一個新行,此處顯示了按下 Enter 鍵的代碼,完整代碼如下所示:

Kotlin override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_ENTER -> { // 撤銷 onKeyUp 並監聽 KEYCODE_ENTER sendMessage() return true // 如果應用已處理按鍵事件則確保返回 true } } // 如果沒有處理事件,則交回系統處理 return super.onKeyUp(keyCode, event) // 如果沒有則將事件傳遞給 super }

媒體鍵支持 (Media key)

如果您的應用希望支持媒體播放,則還需要包含媒體鍵支持。為此請將 Enter 鍵代碼中的 KEYCODE_ENTER 替換為您希望支持的媒體鍵代碼即可,比如這裏使用了 MEDIA_NEXT 和 MEDIA_PREV。此外請不要忘記使用 SPACE 以便用空格鍵來控制播放和暫停。完整代碼如下所示:

Kotlin override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_SPACE, KEYCODE_MEDIA_PLAY_PAUSE -> { playOrpauseMedia(); return true } KEYCODE_MEDIA_NEXT -> {nextTrack(); return true } KEYCODE_MEDIA_PREV -> {prevTrack(); return true } } // 如果沒有處理事件,則交回系統處理 return super.onKeyUp(keyCode, event) }

遊戲鍵支持 (KEYCODE_W|A|S|D)

對於遊戲應用,您可能希望包括對箭頭鍵和 W、A、S、D 四個按鍵的支持,這同樣很簡單。您只需在 Android 文檔中找到正確的 鍵代碼,並監聽這些按鍵即可。完整代碼如下所示:

Kotlin when (keyCode) { KEYCODE_W, DPAD_UP -> { goUp(); return true } KEYCODE_A, DPAD_LEFT -> { goLeft(); return true } KEYCODE_S, DPAD_DOWN -> { goDown(); return true } KEYCODE_D, DPAD_RIGHT -> { goRight(); return true } }

需要注意的是在提供鍵盤支持時通常要監聽 onKeyUp,這樣您就不必擔心在按住某個鍵時,將會發送重複的 onKeyDown 事件。另外如果您想確保實現毫秒級的時間響應,您可以監聽 onKeyDown 並自行處理重複的按鍵事件。完整代碼如下所示:

Kotlin override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_F -> { shootFireball() return true } } return super.onKeyUp(keyCode, event) }

更多相關信息請訪問: ChromeOS.dev

快捷鍵支持 (Ctrl+)

除了基本鍵盤按鍵,還需要考慮的是配置基於 Ctrl 的快捷鍵,複製、粘貼、撤消、重做等,很常見的快捷鍵適用於許多應用。出色的鍵盤支持將會幫助您的應用實現更多的功能,一些應用甚至更進一步將高級功能放在用户觸手可及的地方,比如用户在使用 eDJing 應用時,只需按住 Ctrl 鍵就可以用觸控板搓碟。

如下展示了用於撤消的 Ctrl+Z 快捷鍵的代碼,這部分代碼類似於前面的 onKeyUp 和 onKeyDown 代碼,但使用了 dispatchKeyShortcutEvent 來指示元鍵組合。請注意此時按下 Alt、Ctrl 或 Shift 鍵即可觸發此操作。完整代碼如下所示:

Kotlin override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { return when (event.getKeyCode()) { KEYCODE_Z -> { undoAction() // [Ctrl]+z, [Shift]+z, 或 [Alt]+z 觸發 true } else -> { super.dispatchKeyShortcutEvent(event) } } }

如果您只希望響應特定的元鍵組合,可以使用 Meta_Alt_On,也可以使用類似 isShiftPressed() 或 isCtrlPressed() 的方法。完整代碼如下所示:

Kotlin when { event.isCtrlPressed && event.isShiftPressed -> { redoAction(); true // [Ctrl]+[Shift]+z 觸發 } event.isCtrlPressed -> { undoAction(); true //[Ctrl]+z 觸發 } else -> { // 交給系統處理 super.dispatchKeyShortcutEvent(event) } }

根據此處代碼,只有在同時按下 Ctrl+Z 時才會執行撤消操作,同樣只有在同時按下 Ctrl+Shift+Z 時才會執行重做操作,並不會用到 Alt。

鼠標/觸控板輸入支持

與鍵盤一樣,大多數鼠標和觸控板輸入通常不需要任何額外的代碼就可以工作。但開發者還是有必要使用鼠標測試應用的所有功能,查看是否有任何疏漏。

△ 鼠標

△ 鼠標

右鍵點擊支持

右鍵點擊是最常見的疏漏之一。觸控的一個常見範例是在屏幕上長按以執行基於上下文的操作,但長按鼠標點擊並不直觀。如果要支持右鍵點擊,此處有幾種方案可供選擇。此處顯示了添加上下文菜單的代碼,完整代碼如下所示:

Koltin registerForContextMenu(myView) // 首先為上下文菜單註冊一個或多個視圖,這將自動處理長按和右鍵點擊兩種操作。 ... override fun onCreateContextMenu(menu, view, menuInfo) { super.onCreateContextMenu(menu, view, menuInfo) menuInflater.inflater(R.menu.myContextMenu, menu) // 然後撤銷 overrideonCreateContextMenu 並擴展正確的菜單佈局,同一菜單可用於多個視圖。 } override fun onCreateContextMenu(item: MenuItem): Boolean { return when(item.itemId){ R.id.myMenuItemId -> { menuItemAction(); true } else -> { return super.onContextItemSelected(item) } // 最後,設置 onContextItemSelected 指示選中特定菜單項時需要執行的操作。 } }

對於上下文菜單之外的其他右鍵點擊行為,可以用 onContextClickListener 設置視圖,只需使用它調用在長按用例中使用的相同方法即可。對應代碼如下所示:

Kotlin myView.setOnContextClickListener { performContextAction() true }

懸停響應支持

用户在使用鼠標或觸控板時,通常希望界面能夠以某種方式做出響應。例如當鼠標光標懸停在可點擊的視圖上時會產生視覺反饋,如圖所示,可能是指針圖標發生了變化,又或者出現一些其他視覺指示,這些都可以被用户直觀感受到。此處顯示了指針懸停在視圖上時的代碼,完整代碼如下所示:

Koltin myView.setOnHoverListener { view, motionEvent -> //為視圖設置 onHoverListener when (motionEvent.action) { ACTION_HOVER_ENTER -> { view.pointerIcon = PointerIcon.getSystemIcon( appIicationContext, PointerIcon.TYPE_HAND ) view.setBackgroundColor(Color.BLUE) true } // 監聽 HOVER_ENTER 事件並執行相應的操作。根據代碼顯示指針圖標將變為手形且背景顏色將變為藍色。 ACTION_HOVER_EXIT -> { resetUI(); } else -> { false } // 不要忘記設置當 HOVER_EXIT 發生時重置圖標和背景顏色。 } }

指針捕獲支持

指針捕獲是另一個常見的鼠標和觸控板增強功能,不但對於一些遊戲至關重要,並且還可以為某些應用添加特定功能。應用能夠通過指針捕獲功能捕獲鼠標光標,使光標不出現在屏幕上,這樣無需將光標移動到屏幕邊緣就可以接收相對的指針事件。像 Minecraft: 教育版等第一人稱視角遊戲就是很好的案例。

△ Minecraft: 教育版

△ Minecraft: 教育版

要支持指針捕獲,可以先調用 requestPointerCapture,然後再調用 releasePointerCapture 釋放捕獲的指針。在代碼中可以添加 OnCapturedPointerListener 使用接收的指針數據,並利用指針位置的相對變化來實現一些很棒的功能。完整代碼如下所示:

```Kotlin view.requestPointerCapture() ... view.releasePointerCapture() ... view.setOnCapturedPointerListener { _, motionEvent -> // 計算自從上次 motionEvent 事件後的座標增量 mouseChangeX = motionEvent.x mouseChangey = motionEvent.y

// 計算自從上次 motionEvent 事件後的位移
val totalDistance = hypot(mouseChangeX, mouseChangeY)
doSomethingCool(totalDistance)

} ```

手勢支持

此外 Android API 還提供了高級指針處理,可以添加手勢、雙指張合和縮放支持等,如下圖所示。

如果您希望瞭解更多 Android API 的相關信息,請參閲 Android 開發者網站獲取入門指南——使用輕觸手勢

觸筆輸入支持

如果您已經在應用中添加對指針的出色支持,那麼對於大多數用例來説觸控筆通常能夠按預期正常工作。關於觸控筆的一些增強功能非常值得關注,比如部分設備支持觸控筆傾斜和按壓,這有助於您在繪畫或繪圖應用添加一些出色的控件和功能。此外還有低延遲觸控筆 API 可讓您在繪畫或繪圖應用中獲得最低延遲的顯示響應,並提供可配置的描邊預測,為您打造用筆在紙上繪圖的體驗。如需瞭解實際效果,請在受支持的 Chromebook 或 Android 設備上查看類似於 Concepts 的應用。

△ Concepts 應用對觸控筆支持

△ Concepts 應用對觸控筆支持

  • 如需 瞭解實現細節,請參閲 Android 開發者網站有關 AXIS_PRESSURE 和 AXIS_TILT 的文檔。

  • 低延遲觸控筆 API 庫和演示版應用,請參閲 GitHub

在 Android 模擬器中使用觸控筆

我們與 Microsoft 合作將主機觸控筆支持引入 Android 模擬器中,如果您正在優化應用以提供更高級的觸控筆支持,那麼您將可以在支持的主機上使用 Android 模擬器測試精確的傾斜和按壓控制。

Microsoft Surface Duo 開發者體驗團隊與 Google 合作開展了一項支持高級輸入開發和測試的工作,比如多點觸控分析和觸控筆支持。那麼在模擬器中運行應用時如何使用觸控筆測試應用?

△ 在模擬器中測試觸控筆

△ 在模擬器中測試觸控筆

如圖所示,顯示的是 Surface Studio 上運行的 Microsoft Duo 2 模擬器,此刻有兩款應用在同時運行: 右側窗格是示例應用,該示例允許您測試觸控筆按壓靈敏度、筆方向、擦除筆尖和其他觸控筆按鈕;左側窗格是 Microsoft OneNote 應用,使用模擬器可以在 OneNote 畫布上繪製、做筆記或擦除。

我們非常興奮,在支持觸控的 PC 上,Android 模擬器現在也可以支持多點觸控,這讓您可以測試需要使用多個手指的手勢與應用進行交互,比如雙指張合、縮放和其他觸摸交互。

△ 在 Google 地圖中使用手勢操作

△ 在 Google 地圖中使用手勢操作

這款內置 Android Studio 的可摺疊模擬器正在運行 Google 地圖,只需使用兩個手指就可以放大和縮小地圖。而且這些模擬器更新的不僅是隻支持使用兩個手指,如果您的硬件允許,可以支持多達 10 個觸摸點。

您看到的所有這些變化都不是 Surface Duo 模擬器所特有的,它們也適用於其他可摺疊模擬器。Microsoft 也一直在利用這些模擬器更新來開發和優化自己的應用,例如在包括 Surface Duo、大屏幕和其他可摺疊設備等多種設備類型上測試觸控筆的交互。

手柄輸入支持

如果您有一款遊戲應用則需要添加遊戲手柄支持。使用相應的鍵代碼,確定要對 onKeyUp 還是 onKeyDown 執行操作。

△ 遊戲手柄

△ 遊戲手柄

遊戲手柄方向鍵與鍵盤箭頭鍵的鍵代碼是相同的,只需監聽 KEYCODE_DPAD 事件即可同時處理這兩者。遊戲手柄按鈕也有自己的鍵代碼,您可以監聽這些按鈕就像這裏為 X 按鈕進行的設置一樣。完整代碼如下所示:

Koltin when (keyCode) { BUTTON_X -> { engageNitro(); return true } DPAD_UP, KEYCODE_W -> { goForward(); return true } DPAD_LEFT, KEYCODE_A -> { turnLeft(); return true } ... }

MIDI 輸入支持

當涉及到專門的硬件時,需要針對設備和用例提供支持。MIDI 支持對於音樂和創意工具來説尤其重要,它允許廣泛的、富有表現力的輸入信號,從對壓力敏感的鋼琴鍵盤到具有滑塊、旋鈕、鍵盤等許多不同輸入觸發器的設備,都能提供支持。

如果您希望使用或瞭解更多 MIDI 相關的信息,Android Media Samples 庫中提供了一些便捷的開源示例,可以幫助您開始使用 MIDI。請查看 MidiSynth 項目,特別是該項目中的 Synth Engine 模塊。注意,從 Android 29 開始您還可以使用 NDK MIDI API

回顧

大屏幕的 Android 設備已經出現而且愈發普及,在 Android 上提供出色的輸入支持一直很重要,而對於可摺疊設備、平板電腦和 Chrome 操作系統來説尤為重要。請思考您應用的輸入處理以及如何增加互動、解鎖新功能並提升應用體驗。期待各位開發者投入精力構建精彩的 Android 應用,併為其添加了出色的輸入處理!

歡迎您 點擊這裏 向我們提交反饋,或分享您喜歡的內容、發現的問題。您的反饋對我們非常重要,感謝您的支持!