Когда пользователь фокусируется на редактируемом текстовом компоненте, например TextField, и к устройству подключена аппаратная клавиатура, все вводимые данные обрабатываются системой.
Вы можете добавить быстрые клавиши, настроив обработку событий нажатия клавиш.
Сочетания клавиш по умолчанию
Ниже перечислены сочетания клавиш, доступные по умолчанию.
| Сочетание клавиш | Действие | Composables supporting the shortcut |
|---|---|---|
| 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.
Модификатор принимает лямбду, которая вызывается, когда модифицированный компонент получает ключевое событие.
Ключевое событие описывается как объект KeyEvent.
Информацию о каждом ключевом событии можно получить, обратившись к объекту в лямбда-выражении, переданном модификатору onKeyEvent.
Нажатие клавиши отправляет два ключевых события.
Одно срабатывает, когда пользователь нажимает клавишу, а другое – когда отпускает.
Различить эти два ключевых события можно по атрибуту type объекта KeyEvent.
Возвращаемое значение лямбда-выражения onKeyEvent указывает, обработано ли ключевое событие.
Если приложение обрабатывает событие нажатия клавиши, возвращается значение true, и распространение события прекращается.
В следующем фрагменте кода показано, как вызвать функцию doSomething(), когда пользователь отпускает клавишу S в компоненте Box:
Box( modifier = Modifier .onKeyEvent { if ( it.type == KeyEventType.KeyUp && it.key == Key.S ) { doSomething() true } else { false } } .focusable() ) { Text("Press S key") }
Клавиши-модификаторы
Объект KeyEvent имеет следующие атрибуты, которые указывают, нажаты ли клавиши-модификаторы:
Подробно опишите ключевые события, которые обрабатывает ваше приложение.
В следующем фрагменте кода функция doSomething() вызывается, только если пользователь отпускает клавишу S.
Если пользователь нажимает клавишу-модификатор, например 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") }
События нажатия клавиш Пробел и Ввод
Клавиши Пробел и Ввод также вызывают события клика. Например, пользователи могут запускать и приостанавливать воспроизведение медиаконтента с помощью клавиш Пробел или Ввод, если события клика обрабатываются следующим образом:
MediaPlayer(modifier = Modifier.clickable { togglePausePlay() })
Модификатор clickable перехватывает события клавиш и вызывает обратный вызов onClick() при нажатии клавиши Пробел или Ввод.
Поэтому функция 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 } } )
По умолчанию компонент TextField добавляет символ табуляции каждый раз, когда пользователь нажимает клавишу Tab, даже если событие нажатия клавиши обрабатывается с помощью модификатора onKeyEvent.
Чтобы переместить фокус клавиатуры, не добавляя символы табуляции, обработайте событие нажатия клавиши до того, как будут запущены связанные с ним действия, как показано во фрагменте кода.
Лямбда-выражение onKeyPreviewEvent() перехватывает событие нажатия клавиши, возвращая 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") } }
Лямбда-выражение onPreviewKeyEvent() для компонента Box также не срабатывает, когда пользователи нажимают клавишу Tab.
Сначала вызывается лямбда-выражение onPreviewKeyEvent() в родительском компоненте, а затем – onPreviewKeyEvent() в дочернем.
Вы можете использовать это поведение для реализации сочетаний клавиш на уровне экрана.
Дополнительные ресурсы
- Помощник по быстрым клавишам. Системный экран, на котором пользователи могут искать быстрые клавиши, доступные в вашем приложении.