在大螢幕上,使用者通常會使用鍵盤、滑鼠、觸控板、觸控筆或遊戲手把與應用程式互動。如要讓應用程式接受外部裝置的輸入,請執行下列步驟:
- 測試基本鍵盤支援,例如按 Tab 鍵和方向鍵瀏覽鍵盤、輸入按鍵文字確認,以及在媒體應用程式中按空格鍵播放及暫停。
- 在適用的情況下新增標準鍵盤快速鍵;例如,按下 Ctrl + Z 鍵即可復原,按下 Ctrl + S 鍵即可儲存
- 測試基本的滑鼠互動,方法包括以滑鼠右鍵按一下內容選單、滑鼠遊標懸停圖示變化,以及在自訂檢視畫面上以滑鼠滾輪或觸控板捲動事件
- 測試應用程式專屬的輸入裝置,例如繪圖應用程式用的觸控筆、遊戲控制器及音樂應用程式用的 MIDI 控制器
- 考慮進階的輸入支援,讓應用程式能在桌面環境中脫穎而出;舉例來說,觸控板可運用於 DJ 應用程式的交替轉換、遊戲的滑鼠擷取等功能,以及進階使用者專屬的擴展鍵盤快速鍵
鍵盤
應用程式回應鍵盤輸入的方式,有助打造良好的大螢幕體驗。鍵盤輸入有三種,分別為導覽、按鍵及快速鍵。
導覽
鍵盤導覽功能極少用在以觸控為主的應用程式,但使用者如果在操作應用程式時使用鍵盤,會希望有鍵盤導覽的功能。如果使用者有手機、平板電腦、摺疊式裝置和電腦裝置的無障礙需求,這點也非常重要。
許多應用程式都只需要使用簡單的方向鍵和分頁導覽功能,大部分可以透過 Android 架構自動處理。舉例來說,Button
的檢視畫面預設為可聚焦,而鍵盤導覽一般不需要任何多餘的程式碼即可運作。如要讓預設為無法聚焦的檢視畫面啟用鍵盤導覽,開發人員應將其標示為可聚焦,作法可透過程式輔助或是以 XML 中完成,如下所示。詳情請參閱聚焦 處理一文。
Kotlin
yourView.isFocusable = true
Java
yourView.setFocusable(true);
或者,也可以在版面配置檔案中設定 focusable
屬性:
android:focusable="true"
啟用聚焦功能後,Android 架構就會根據位置,建立所有可聚焦檢視畫面的對應導覽。通常這些可正常運作,無須做進一步的處理。如果應用程式的預設對應不正確,可依照以下方式覆寫:
Kotlin
// Arrow keys yourView.nextFocusLeftId = R.id.view_to_left yourView.nextFocusRightId = R.id.view_to_right yourView.nextFocusTopId = R.id.view_above yourView.nextFocusBottomId = R.id.view_below // Tab key yourView.nextFocusForwardId = R.id.next_view
Java
// Arrow keys yourView.setNextFocusLeftId(R.id.view_to_left); yourView.setNextFocusRightId(R.id.view_to_left); yourView.setNextFocusTopId(R.id.view_to_left); yourView.setNextFocusBottomId(R.id.view_to_left); // Tab key yourView.setNextFocusForwardId(R.id.next_view);
建議在每次發布版本前,嘗試只使用鍵盤存取應用程式的每一個功能。必須可以在不須使用滑鼠或觸控輸入的情況下,輕鬆存取最常見的操作。
提醒您,對於有無障礙需求的使用者來說,鍵盤支援十分重要。
按鍵輸入
使用螢幕虛擬鍵盤處理的文字輸入功能 (IME),例如 EditText
,應用程式要能如預期地在大螢幕裝置上正常運作,且開發人員不需再另行處理。對於架構無法預測的按鍵動作,應用程式必須自行處理其行為。這對於含有自訂檢視畫面的應用程式而言尤其重要。
例如使用 Enter 鍵傳送訊息的即時通訊應用程式、使用空格鍵啟動及停止播放的媒體應用程式,以及透過 w、a、s 和 d 鍵控制移動的遊戲等。
多數應用程式會覆寫 onKeyUp()
回呼,並為各個收到的鍵盤程式碼新增預期行為,如下所示:
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }
Java
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_ENTER) { sendMessage(); return true; } else if (KeyEvent.KEYCODE_SPACE){ playOrPauseMedia(); return true; } else { return super.onKeyUp(keyCode, event); } }
釋放按鍵時,就會發生 onKeyUp
事件。使用這個回呼可避免按下按鍵或釋放緩慢時,應用程式無需處理多個 onKeyDown
事件。想要得知按下按鍵的時機,或是預期使用者按住鍵盤鍵的遊戲和應用程式,可以查詢 onKeyDown()
事件,並自行處理重複的 onKeyDown
事件。
若要進一步瞭解如何支援鍵盤,請參閱處理鍵盤操作。
捷徑
使用硬體鍵盤時,最常使用的是 Ctrl、Alt 和 Shift 組成的快速鍵。如果應用程式不執行這些項目,使用者可能會感到困擾。進階使用者也喜歡為常用的應用程式特定工作設定快速鍵。快速鍵能讓應用程式使用起來更方便,使其與沒有快捷鍵的應用程式有所區隔。
常見的快速鍵包括 Ctrl + S (儲存)、Ctrl + Z (復原) 和 Ctrl + Shift + Z (重做)。如需更進階的捷徑範例,請參閱 VLC Media Player 快速鍵清單。
您可以使用 dispatchKeyShortcutEvent()
實作捷徑。這會攔截給定鍵碼的所有中繼資料鍵組合 (Alt、Ctrl 和 Shift)。如要檢查特定的中繼資料鍵,請使用 KeyEvent.isCtrlPressed()
、KeyEvent.isShiftPressed()
、KeyEvent.isAltPressed()
或 KeyEvent.hasModifiers()
,
將快速鍵代碼與其他按鍵動作處理功能 (例如 onKeyUp()
和 onKeyDown()
) 分隔開來可以讓程式碼維護起來更加簡單,而且可以開啟預設接受中繼資料鍵的功能,而不需每次都手動實作中繼資料鍵的檢查。對於習慣不同鍵盤配置和作業系統的使用者,允許所有中繼資料鍵的組合使用起來會更加方便。
Kotlin
override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { return when (event.keyCode) { KeyEvent.KEYCODE_O -> { openFile() // Ctrl+O, Shift+O, Alt+O true } KeyEvent.KEYCODE_Z-> { if (event.isCtrlPressed) { if (event.isShiftPressed) { redoLastAction() // Ctrl+Shift+Z pressed true } else { undoLastAction() // Ctrl+Z pressed true } } } else -> { return super.dispatchKeyShortcutEvent(event) } } }
Java
@Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_O) { openFile(); // Ctrl+O, Shift+O, Alt+O return true; } else if(event.getKeyCode() == KeyEvent.KEYCODE_Z) { if (event.isCtrlPressed()) { if (event.isShiftPressed()) { redoLastAction(); return true; } else { undoLastAction(); return true; } } } return super.dispatchKeyShortcutEvent(event); }
也可以在 onKeyUp()
中實作快速鍵,方法是檢查 KeyEvent.isCtrlPressed()
、KeyEvent.isShiftPressed()
或 KeyEvent.isAltPressed()
,方法與上述相同。如果中繼行為對應用程式來說比較像是行為的修改,而不是快捷鍵,維護起來會較為簡單。舉例來說,W 代表「向前走」,而 Shift + W 則代表「向前跑」。
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_W-> { if (event.isShiftPressed) { if (event.isCtrlPressed) { flyForward() // Ctrl+Shift+W pressed true } else { runForward() // Shift+W pressed true } } else { walkForward() // W pressed true } } else -> super.onKeyUp(keyCode, event) } }
Java
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_W) { if (event.isShiftPressed()) { if (event.isCtrlPressed()) { flyForward(); // Ctrl+Shift+W pressed return true; } else { runForward(); // Shift+W pressed return true; } } else { walkForward(); return true; } } return super.onKeyUp(keyCode, event); }
觸控筆
許多大螢幕裝置都配備觸控筆,Android 應用程式則將其視為觸控螢幕輸入。部分裝置也可能有 USB 或藍牙繪圖桌,例如 Wacom Intuos。Android 應用程式可以接收藍牙輸入,但不支援 USB 輸入。
觸控筆事件會透過 View.onTouchEvent()
或 View.onGenericMotionEvent()
報告為觸控螢幕事件,並包含 SOURCE_STYLUS
類型的 MotionEvent.getSource()
。
MotionEvent
也具有其他資料:
MotionEvent.getToolType()
會回傳TOOL_TYPE_FINGER
、TOOL_TYPE_STYLUS 或TOOL_TYPE_ERASER
,具體取決於與介面互動的工具而定MotionEvent.getPressure()
會回報施用在觸控筆上的實體壓力 (如果支援)MotionEvent.getAxisValue()
搭配MotionEvent.AXIS_TILT
和MotionEvent.AXIS_ORIENTATION
,可用來讀取觸控筆的實體傾斜和方向 (如果支援)
歷史點
Android 會批次處理輸入事件,並以每個頁框傳送一次。觸控筆報告事件的頻率會高於螢幕的頻率。建立繪圖應用程式時,請務必使用 getHistorical
API 檢查近期過去的事件:
MotionEvent.getHistoricalX()
MotionEvent.getHistoricalY()
MotionEvent.getHistoricalPressure()
MotionEvent.getHistoricalAxisValue()
防止誤觸
使用者使用觸控筆繪圖、書寫或與應用程式互動時,他們的手掌有時可能會碰到螢幕。觸控事件 (設為 ACTION_DOWN
或 ACTION_POINTER_DOWN
) 可以在系統辨識並忽略手掌誤觸之前回報給您的應用程式。
Android 會分派 MotionEvent
,藉以取消手掌觸控事件。如果您的應用程式收到 ACTION_CANCEL
,請取消手勢。如果您的應用程式收到 ACTION_POINTER_UP
,請檢查是否已設定 FLAG_CANCELED
。如已設定,請取消手勢。
不要只檢查 FLAG_CANCELED
。為方便起見,自 Android 13 起,系統會為 ACTION_CANCEL
事件設定 FLAG_CANCELED
,但之前的版本不會。
Android 12
在 Android 12 (API 級別 32) 以下版本中,系統只能針對單指標觸控事件進行防止誤觸偵測。如果手掌輕觸是唯一的指標,系統則會在動作事件物件上設定 ACTION_CANCEL
,以取消該事件。如果其他指標停擺,系統會設定 ACTION_POINTER_UP
,但這樣仍不足以進行防止誤觸偵測。
Android 13
在 Android 13 (API 級別 33) 以上版本中,如果手掌輕觸是唯一的指標,系統則會在動作事件物件上設定 ACTION_CANCEL
和 FLAG_CANCELED
,以取消該事件。如果其他指標停擺,系統則會設定 ACTION_POINTER_UP
和 FLAG_CANCELED
。
每當應用程式收到具有 ACTION_POINTER_UP
的動作事件時,請檢查 FLAG_CANCELED
,以便判斷該事件是否表示防止誤觸 (或其他事件取消)。
筆記應用程式
ChromeOS 有一項特殊意圖,可向使用者顯示已註冊的筆記應用程式。如要將應用程式註冊為筆記應用程式,請在 Android 資訊清單中加入以下內容:
<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
使用者完成註冊後,即可將該應用程式選定為預設的筆記應用程式。當系統要求新的筆記時,應用程式應建立一個空白筆記,供觸控筆輸入內容。使用者想要為圖片加上註解時 (例如螢幕截圖或下載圖片),應用程式會以 ClipData
啟動,其中包含一或多個具備 content://
URI 的項目。應用程式應建立一項附註,利用第一個附加的圖片做為背景圖片,並進入使用者透過觸控筆在螢幕上繪圖的模式。
測試不使用觸控筆情況下的筆記意圖
如要測試應用程式是否能正確回應不使用觸控筆情況下的筆記意圖,請使用以下方式在 ChromeOS 中顯示筆記選項:
- 切換至開發人員模式,將裝置設為寫入模式
- 按下 Ctrl + Alt + F2 鍵開啟終端機
- 執行
sudo vi /etc/chrome_dev.conf
指令。 - 按下
i
編輯檔案,並在檔案尾端加入一行新的--ash-enable-palette
- 按下 Esc 鍵儲存,輸入 :、w、q,然後按下 Enter 鍵
- 按下 Ctrl + Alt + F1 鍵,返回一般 ChromeOS UI
- 登出後再重新登入
檔案櫃現在應該會顯示觸控筆選單:
- 輕觸檔案櫃中的觸控筆按鈕,然後選擇「New note」。一個空白的繪圖筆記應該會開啟。
- 擷取螢幕截圖。從檔案櫃中依序選取「stylus button」>「Capture screen」,或是下載一張圖片。通知中應會出現「為圖片加上註解」的選項。這個選項會啟動應用程式,準備為該圖片加上註解。
支援滑鼠和觸控板
大多數應用程式通常只需要處理三個以大螢幕為主的事件:按一下滑鼠右鍵、懸停,以及拖曳。
按一下滑鼠右鍵
任何會導致應用程式顯示內容選單的操作 (例如按住清單項目) 也應該回應按一下滑鼠右鍵的事件。若要處理按一下滑鼠右鍵的事件,應用程式應註冊 View.OnContextClickListener
。若要進一步瞭解如何建立內容選單,請參閱建立內容選單。
Kotlin
yourView.setOnContextClickListener { showContextMenu() true }
Java
yourView.setOnContextClickListener(v -> { showContextMenu(); return true; });
懸停
開發人員可以透過處理懸停事件,讓應用程式版面配置看起來更精美流暢。這對自訂檢視畫面來說尤其重要。兩個最常見的範例為:
- 變更滑鼠游標圖示,告訴使用者某元素具有可互動行為 (例如可點擊或可編輯)
- 當指標懸停在大型清單或格狀項目上時,對項目加上可見的回饋內容
Kotlin
// Change the icon to a "hand" pointer on hover, // Highlight the view by changing the background. yourView.setOnHoverListener { view, _ -> addVisualHighlighting(true) view.pointerIcon = PointerIcon.getSystemIcon(view.context, PointerIcon.TYPE_HAND) false // listener did not consume the event. }
Java
yourView.setOnHoverListener((view, event) -> { addVisualHighlighting(true); view.setPointerIcon(PointerIcon .getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND)); return true; });
拖曳
在多視窗環境中,使用者會希望可以在不同應用程式之間拖曳項目。這種情況發生於桌上型裝置,以及處於分割畫面模式的平板電腦、手機和折疊式裝置。
開發人員應考慮使用者是否會將項目拖曳到應用程式中。常見的範例包括:相片編輯器應預期會接收到相片、音訊播放器應預期會接收到音訊檔案,而繪圖程式應預期會接收到相片。
如要新增拖曳支援功能,請參閱 Android 說明文章「拖曳」和這篇 ChromeOS 網誌文章。
ChromeOS 的特殊注意事項
- 請務必透過
requestDragAndDropPermissions
要求權限,存取從應用程式外部拖曳進來的項目 - 項目必須具有
View.DRAG_FLAG_GLOBAL
旗標,才能拖曳至其他應用程式
進階指標支援
應用程式對滑鼠和觸控板輸入進行進階的處理時,應遵守針對 View.onGenericMotionEvent()
的 Android 說明文件,並使用 MotionEvent.getSource()
來區分 SOURCE_MOUSE
與 SOURCE_TOUCHSCREEN
。
檢查 MotionEvent
以實作必要的行為:
- 動作會產生
ACTION_HOVER_MOVE
事件。 - 按鈕會產生
ACTION_BUTTON_PRESS
及ACTION_BUTTON_RELEASE
事件。您也可以使用getButtonState()
查看目前所有滑鼠/觸控板按鈕的狀態。 - 滑鼠滾輪的捲動會產生
ACTION_SCROLL
事件。
遊戲控制器
部分大螢幕 Android 裝置可支援多達四個遊戲控制器。開發人員應使用標準 Android 遊戲控制器 API 來處理它們 (請參閱支援遊戲控制器)。
按鈕是對應至常用的值,同時使用常見的對應。但很遺憾地,並非所有遊戲控制器製造商都遵守相同的對應慣例。如果您可以讓使用者選取不同的熱門控制器對應關係,即可提供更優質的體驗。詳情請參閱處理遊戲手把按鈕的按下動作一文。
輸入平移模式
ChromeOS 預設會啟用輸入平移模式。在大多數的 Android 應用程式中,此模式可讓應用程式在電腦環境中正常運作。例如在觸控板上自動啟用雙指捲動功能、滑鼠滾輪捲動,以及將原始顯示座標對應至視窗座標。一般來說,應用程式開發人員不需自行實作上述任何行為。
如果應用程式執行了自訂的輸入行為 (例如定義自訂的雙指觸控板雙指撥動操作),或是這些輸入平移無法提供應用程式預期的輸入事件,您可以停用輸入平移模式,只要在 Android 資訊清單中加入下列標記即可:
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
其他資源
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 強化 Android 應用程式中的觸控筆支援
- 自訂文字編輯器
- 平板電腦和大螢幕支援功能