사용자가 TextField와 같은 수정 가능한 텍스트 구성요소에 포커스를 두고 기기에 하드웨어 키보드가 연결되어 있으면 모든 입력이 시스템에 의해 처리됩니다.
키 이벤트를 처리하여 키보드 단축키를 제공할 수 있습니다.
기본 키보드 단축키
다음 키보드 단축키는 기본적으로 사용할 수 있습니다.
| 키보드 단축키 | 작업 | 단축키를 지원하는 컴포저블 |
|---|---|---|
| Shift+Ctrl+왼쪽 화살표/오른쪽 화살표 | 단어의 시작/끝까지 텍스트 선택 | TextField BasicTextField |
| Shift+Ctrl+위쪽 화살표/아래쪽 화살표 | 단락의 시작/끝까지 텍스트 선택 | TextField BasicTextField |
| Shift+Alt+위쪽 화살표/아래쪽 화살표 또는 Shift+Meta+왼쪽 화살표/오른쪽 화살표 | 텍스트 시작/끝까지 텍스트 선택 | TextField BasicTextField |
| Shift+왼쪽 화살표/오른쪽 화살표 | 캐릭터 선택 | TextField BasicTextField |
| Ctrl+A | 모두 선택 | TextField BasicTextField |
| Ctrl+C/Ctrl+X/Ctrl+V | 복사/잘라내기/붙여넣기 | TextField BasicTextField |
| Ctrl+Z/Ctrl+Shift+Z | 실행취소/다시 실행 | TextField BasicTextField |
| PageDown/PageUp | 스크롤 | LazyColumn, verticalScroll 수정자, scrollable 수정자 |
주요 이벤트
Compose에서는 onKeyEvent 수정자를 사용하여 개별 키 입력을 처리할 수 있습니다.
이 수정자는 수정자를 사용한 구성요소가 키 이벤트를 수신할 때 호출되는 람다를 허용합니다.
키 이벤트는 KeyEvent 객체로 설명됩니다.
onKeyEvent 수정자에 전달된 람다의 객체를 참조하여 각 키 이벤트의 정보를 가져올 수 있습니다.
키 입력은 두 개의 키 이벤트를 전송합니다.
하나는 사용자가 키를 누를 때 트리거되고 다른 하나는 키를 놓을 때 트리거됩니다.
KeyEvent 객체의 type 속성을 참조하여 두 가지 주요 이벤트를 구분할 수 있습니다.
onKeyEvent 람다의 반환 값은 키 이벤트가 처리되는지 여부를 나타냅니다.
앱이 키 이벤트를 처리하는 경우 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() 함수는 호출되지 않습니다.
D 키를 놓는 것과 같은 InnerComponent의 다른 키 이벤트는 OuterComponent에서 처리할 수 있습니다.
D 키를 놓는 키 이벤트가 OuterComponent에 전파되므로 actionC() 함수가 호출됩니다.
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 구성요소는 키 이벤트가 onKeyEvent 수정자로 처리되더라도 사용자가 Tab 키를 누를 때마다 탭 문자를 추가합니다.
탭 문자를 추가하지 않고 키보드 포커스를 이동하려면 스니펫과 같이 키 이벤트와 연결된 작업을 트리거하기 전에 키 이벤트를 처리합니다.
onKeyPreviewEvent() 람다는 true를 반환하여 키 이벤트를 가로챕니다.
상위 구성요소는 하위 요소에서 발생하는 키 이벤트를 가로챌 수 있습니다.
다음 스니펫에서는 사용자가 S 키를 누르면 actionForPreview() 함수를 호출하는 대신 previewSKey() 함수가 호출됩니다.
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() 람다가 트리거되지 않습니다.
onPreviewKeyEvent() 람다는 상위 구성요소에서 먼저 호출된 후 하위 구성요소의 onPreviewKeyEvent()가 호출됩니다.
이 동작을 활용하여 화면 전체 키보드 단축키를 구현할 수 있습니다.
추가 리소스
- 키보드 단축키 도우미: 사용자가 앱에서 제공하는 키보드 단축키를 검색할 수 있는 시스템 화면입니다.