當使用者將焦點放在可編輯的文字元件 (例如 TextField),且裝置已連接硬體鍵盤時,所有輸入內容都會由系統處理。您可以透過處理按鍵事件來提供鍵盤快速鍵。
預設鍵盤快速鍵
以下是預設可用的鍵盤快速鍵。
| 鍵盤快速鍵 | 動作 | 支援快速鍵的可組合項 |
|---|---|---|
| Shift + Ctrl + 向左鍵/向右鍵 | 選取文字至字詞開頭/結尾 | BasicTextField、TextField |
| Shift + Ctrl + 向上鍵/向下鍵 | 選取文字至段落開頭/結尾 | BasicTextField、TextField |
| Shift + Alt + 向上鍵/向下鍵或 Shift + Meta + 向左鍵/向右鍵 | 選取文字至文字開頭/結尾 | BasicTextField、TextField |
| Shift + 向左鍵/向右鍵 | 選取角色 | BasicTextField、TextField |
| Ctrl+A | 全選 | BasicTextField、TextField |
| Ctrl + C/Ctrl + X/Ctrl + V 鍵 | 複製/剪下/貼上 | BasicTextField、TextField |
| Ctrl+Z/Ctrl+Shift+Z | 復原/重做 | BasicTextField、TextField |
| PageDown/PageUp | 捲動 | LazyColumn、verticalScroll 修飾符、scrollable 修飾符 |
重要活動
在 Compose 中,您可以使用 onKeyEvent 修飾符處理個別按鍵操作。這個修飾符接受 lambda,當被修飾的元件收到按鍵事件時,系統會呼叫此 lambda。重要事件會以 KeyEvent 物件的形式描述。您可以參照傳遞至 onKeyEvent 修飾符的 lambda 中的物件,取得每個按鍵事件的資訊。
按鍵動作會傳送兩個按鍵事件。一個在使用者按下按鍵時觸發,另一個則在放開按鍵時觸發。您可以參考 KeyEvent 物件的 type 屬性,區分這兩個重要事件。
onKeyEvent lambda 的傳回值會指出是否已處理按鍵事件。如果應用程式處理按鍵事件,請傳回 true,停止事件傳播。
下列程式碼片段說明如何在使用者放開 Box 元件上的 S 鍵時,呼叫 doSomething() 函式:
Box( modifier = Modifier .onKeyEvent { if ( it.type == KeyEventType.KeyUp && it.key == Key.S ) { doSomething() true } else { false } } .focusable() ) { Text("Press S key") }
輔助鍵
KeyEvent 物件具有下列屬性,可指出是否按下輔助鍵:
具體描述應用程式處理的重要事件。下列程式碼片段只有在使用者放開 S 鍵時,才會呼叫 doSomething() 函式。如果使用者按下任何輔助鍵 (例如 Shift 鍵),應用程式就不會呼叫函式。
Box( modifier = Modifier .focusable() .onKeyEvent { if ( it.type == KeyEventType.KeyUp && it.key == Key.S && !it.isAltPressed && !it.isCtrlPressed && !it.isMetaPressed && !it.isShiftPressed ) { doSomething() true } else { false } } ) { Text("Press S key with a modifier key") }
空白鍵和 Enter 鍵點擊事件
空白鍵和 Enter 鍵也會觸發點擊事件。舉例來說,使用者可以透過處理點擊事件,使用空格鍵或 Enter 鍵切換 (播放或暫停) 媒體播放,如下所示:
MediaPlayer(modifier = Modifier.clickable { togglePausePlay() })
clickable 修飾符會攔截按鍵事件,並在按下空白鍵或 Enter 鍵時呼叫 onClick() 回呼。因此,在程式碼片段中按下空格鍵或 Enter 鍵,即可呼叫 togglePausePlay() 函式。
未使用的重要事件
未使用的重要事件會從事件發生的元件,傳播到外層元件。在以下範例中,InnerComponent 會在 S 鍵放開時消耗按鍵事件,因此 OuterComponent 不會收到放開 S 鍵觸發的任何按鍵事件。因此系統不會呼叫 actionB() 函式。
InnerComponent 上的其他按鍵事件 (例如放開 D 鍵) 可由 OuterComponent 處理。系統會呼叫 actionC() 函式,因為放開 D 鍵的按鍵事件會傳播至 OuterComponent。
OuterComponent( modifier = Modifier.onKeyEvent { when { it.type == KeyEventType.KeyUp && it.key == Key.S -> { actionB() // This function is never called. true } it.type == KeyEventType.KeyUp && it.key == Key.D -> { actionC() true } else -> false } } ) { InnerComponent( modifier = Modifier.onKeyEvent { if (it.type == KeyEventType.KeyUp && it.key == Key.S) { actionA() true } else { false } } ) }
onKeyPreviewEvent 修飾符
在某些用途中,您可能需要在按鍵事件觸發預設動作前攔截該事件。例如,在 TextField 中新增自訂快速鍵。下列程式碼片段可讓使用者按下 Tab 鍵,移至下一個可聚焦的元件。
val focusManager = LocalFocusManager.current var textFieldValue by remember { mutableStateOf(TextFieldValue()) } TextField( textFieldValue, onValueChange = { textFieldValue = it }, modifier = Modifier.onPreviewKeyEvent { if (it.type == KeyEventType.KeyUp && it.key == Key.Tab) { focusManager.moveFocus(FocusDirection.Next) true } else { false } } )
根據預設,每當使用者按下 Tab 鍵時,TextField 元件就會新增一個 Tab 字元,即使按鍵事件是以 onKeyEvent 修飾符處理也一樣。如要移動鍵盤焦點而不新增任何 Tab 字元,請在觸發與按鍵事件相關聯的動作之前處理按鍵事件,如程式碼片段所示。onKeyPreviewEvent() lambda 會傳回 true,藉此攔截按鍵事件。
父項元件可以攔截子項上發生的按鍵事件。在下列程式碼片段中,使用者按下 S 鍵時,系統會呼叫 previewSKey() 函式,而不是 actionForPreview() 函式。
Column( modifier = Modifier.onPreviewKeyEvent { if (it.key == Key.S) { previewSKey() true } else { false } } ) { Box( modifier = Modifier .focusable() .onPreviewKeyEvent { actionForPreview(it) false } .onKeyEvent { actionForKeyEvent(it) true } ) { Text("Press any key") } }
使用者按下 Tab 鍵時,也不會觸發 Box 元件的 onPreviewKeyEvent() lambda。系統會先在父項元件上呼叫 onPreviewKeyEvent() lambda,然後在子項元件中呼叫 onPreviewKeyEvent()。您可以利用這項行為,實作全螢幕鍵盤快速鍵。
其他資源
- 鍵盤快速鍵協助工具:系統畫面,可讓使用者搜尋應用程式提供的鍵盤快速鍵。