處理鍵盤動作

當使用者將焦點移至可編輯的文字元件 (例如 TextField) 時, 裝置也配備實體鍵盤 所有輸入內容都是由系統處理 您可以透過處理按鍵事件提供鍵盤快速鍵。

預設鍵盤快速鍵

下列鍵盤快速鍵可供使用。

鍵盤快速鍵 動作 支援捷徑的可組合項
Shift + Ctrl + 向左鍵/向右鍵 選取文字至字詞的開頭/結尾 BasicTextFieldTextField
Shift + Ctrl + 向上鍵/向下鍵 選取文字至段落開頭/結尾 BasicTextFieldTextField
Shift + Alt + 向上鍵/向下鍵Shift + Meta + 向左鍵/向右鍵 選取文字至文字開頭/結尾 BasicTextFieldTextField
Shift + 向左鍵/向右鍵 選取字元 BasicTextFieldTextField
Ctrl + A 全選 BasicTextFieldTextField
Ctrl + C/Ctrl + X/Ctrl + V 複製/剪下/貼上 BasicTextFieldTextField
Ctrl + Z/Ctrl + Shift + Z 復原/重做 BasicTextFieldTextField
PageDown/PageUp 捲動 LazyColumnverticalScroll 修飾符、scrollable 修飾符

重要活動

在 Compose 中,您可以使用 onKeyEvent 修飾符來處理個別按鍵輸入。這個修飾符會接受 lambda,在修飾元件收到按鍵事件時呼叫此 lambda。重要事件的定義為 KeyEvent 物件。 參照物件即可取得每個重要事件的資訊 在傳遞至 onKeyEvent 修飾符的 lambda 中。

按鍵動作會傳送兩個按鍵事件。 1 會在使用者按下按鍵時觸發。 另一個則會在金鑰釋放時觸發 您可以區分 方法是參照 KeyEvent 物件的 type 屬性。

onKeyEvent lambda 的傳回值會指出是否已處理按鍵事件。如果應用程式處理按鍵事件,請傳回 true,以停止事件的傳播。

下列程式碼片段說明如何在使用者釋放 Box 元件上的 S 鍵時,呼叫 doSomething() 函式:

Box(
    modifier = Modifier.focusable().onKeyEvent {
        if(
            it.type == KeyEventType.KeyUp &&
            it.key == Key.S
        ) {
            doSomething()
            true
        } else {
            false
        }
    }
)  {
    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 鍵 切換 (播放或暫停) 媒體播放,方法如下:

MoviePlayer(
   modifier = Modifier.clickable { togglePausePlay() }
)

clickable 修飾符會攔截按鍵事件,並在按下 空格鍵Enter 鍵時呼叫 onClick() 回呼。因此,您只要在程式碼片段中按下 空格鍵Enter 鍵,即可呼叫 togglePausePlay() 函式。

未使用的按鍵事件

未使用的重要事件會從發生事件的元件傳播至包含的封閉式外部元件。在下方範例中,InnerComponent 會在 S 鍵釋放時使用按鍵事件,因此 OuterComponent 不會收到因釋放 S 鍵而觸發的任何按鍵事件。因此,系統不會呼叫 actionB() 函式。

InnerComponent 上的其他按鍵事件 (例如釋放 D 鍵) 可由 OuterComponent 處理。系統會呼叫 actionC() 函式,因為 就會對 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
        }
    }
)

根據預設,TextField 元件會在使用者每次按下 Tab 鍵時新增一個 Tab 字元,即使使用 onKeyEvent 修飾符處理按鍵事件也是如此。如要移動鍵盤焦點,但不新增任何 Tab 字元,請在觸發與按鍵事件相關聯的動作之前處理按鍵事件,如程式碼片段所示。onKeyPreviewEvent() lambda 會攔截按鍵事件 方法是傳回 true

父項元件可攔截子項發生的按鍵事件。在以下程式碼片段中,系統會呼叫 previewSKey() 函式。 當使用者按下 S 鍵時 而不是呼叫 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")
  }
}

不會觸發 Box 元件的 onPreviewKeyEvent() lambda 當使用者按下 Tab 鍵。 系統會先在父項元件上呼叫 onPreviewKeyEvent() lambda。 然後在子項元件中呼叫 onPreviewKeyEvent()。 您可以利用這項行為實作全螢幕鍵盤快速鍵。

其他資源