Как закрыть виртуальную клавиатуру из текстового поля Jetpack Compose?
Я использую Jetpack Compose TextField
и я хочу закрыть виртуальную клавиатуру, когда пользователь нажимает кнопку действия (imeActionPerformed
параметр).
val text = +state { "" }
TextField(
value = text.value,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done,
onImeActionPerformed = {
// TODO Close the virtual keyboard here <<<
}
onValueChange = { s -> text.value = s }
)
8 ответов
С 1.0.0-alpha01
вы можете использовать SoftwareKeyboardController
класс:
var text by remember { mutableStateOf(TextFieldValue("Text")) }
TextField(
value = text,
onValueChange = {
text = it
},
label = { Text("Label") },
imeAction = ImeAction.Done,
onImeActionPerformed = { action, softwareController ->
if (action == ImeAction.Done) {
softwareController?.hideSoftwareKeyboard()
}
}
)
По версии создания письма 1.0.0-alpha12onImeActionPerformed
устарел, и предлагаемый подход заключается в использовании
keyboardActions
с комбинацией
keyboardOptions
:
val focusManager = LocalFocusManager.current
OutlinedTextField(
value = ...,
onValueChange = ...,
label = ...,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done, keyboardType = KeyboardType.Password),
)
focusManager.clearFocus()
позаботится об удалении мягкой клавиатуры.
В
1.0.0
вы можете использовать
SoftwareKeyboardController
или
FocusManager
сделать это.
Этот ответ фокусируется на их различиях.
Настраивать:
var text by remember { mutableStateOf("")}
TextField(
value = text,
onValueChange = { text = it },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { /* TODO */ }),
)
SoftwareKeyboardController:
На основе
@Gabriele Mariottis
отвечать.
val keyboardController = LocalSoftwareKeyboardController.current
// TODO =
keyboardController?.hide()
Это только закрывает клавиатуру, но НЕ очищает фокус от любого сфокусированного текстового поля (обратите внимание на толстое подчеркивание).
FocusManager:
На основе
@azizbekians
отвечать.
val focusManager = LocalFocusManager.current
// TODO =
focusManager.clearFocus()
Это закрывает клавиатуру И очищает фокус от TextField.
Скрытие клавиатуры при нажатии кнопки
Чтобы добавить решение Габриэле Мариотти , если вы хотите условно скрыть клавиатуру, скажем, после нажатия кнопки, используйте это:
keyboardController?.hide()
Например, скрыть клавиатуру после нажатия кнопки Добавить:
var newWord by remember { mutableStateOf("") }
val keyboardController = LocalSoftwareKeyboardController.current
// Setup the text field with keyboard as provided by Gabriele Mariotti
...
Button(
modifier = Modifier
.height(56.dp),
onClick = {
if (!newWord.trim().isNullOrEmpty()) {
wordViewModel.onAddWord(newWord.trim())
newWord = ""
keyboardController?.hide()
}
...
Есть два сценария
Сценарий 1. TextField в AlertDialog
Обязательно инициализируйте
keyboard controller
или
focus manager
внутри
Dialog content scope
(Dialog имеет собственный контроллер клавиатуры)
Dialog(
onDismissRequest = {
// on dismiss
}
) {
// initialise the keyboard controller and focus Manager inside the content scope
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
}
скрыть клавиатуру
keyboardController?.hide()
focusManager.clear()
Крайний регистр: закрыть диалоговое окно и скрыть клавиатуру.
При одновременном закрытии диалогового окна и клавиатуры может возникнуть проблема с мерцанием клавиатуры (быстрое скрытие и отображение клавиатуры).
Попробуйте сначала скрыть клавиатуру, а затем вызвать событие диалогового окна закрытия с задержкой.
Dialog() {
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
Button(onClick = {
keyboardController?.hide()
focusManager.clear()
// notify the view model to dismiss the dialog
viewModel.onNegativeButtonClicked()
})
}
Внутри модели представления
ViewModel {
fun onNegativeButtonClicked() {
// trigger dismissDialog event with delay
}
}
Сценарий 2 — только TextField (без диалогового окна)
val keyboardController = LocalSoftwareKeyboardController.current
var text by rememberSaveable { mutableStateOf("") }
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
// do something here
}
)
)
или вы можете просто использоватьkeyboardController
focusManager
скрыть клавиатуру внутри события щелчка
Button(onClick = {
keyboardController?.hide()
})
Я нашел решение здесь:)
fun hideKeyboard(activity: Activity) {
val imm: InputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
var view = activity.currentFocus
if (view == null) {
view = View(activity)
}
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
Мне просто нужно вызвать указанную выше функцию из моего компонента:
// getting the context
val context = +ambient(ContextAmbient)
// textfield state
val text = +state { "" }
TextField(
value = text.value,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done,
onImeActionPerformed = {
if (imeAction == ImeAction.Done) {
hideKeyboard(context as Activity)
}
}
onValueChange = { s -> text.value = s }
)
Я нашел способ отключить его в CoreTextField, используя TextInputService для управления переключателем
val focus = LocalTextInputService.current
var text by remember{ mutableStateOf("")}
TextField(
value = text,
onValueChange = { text = it },
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done, keyboardType = KeyboardType.Text),
keyboardActions = KeyboardActions(onDone = { focus?.hideSoftwareKeyboard() }),
singleLine = true
)
реализация 'androidx.compose.material3:material3:1.0.0-alpha02'
Текстовое поле со скрытой клавиатурой при действии Ime
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun TextFieldWithHideKeyboardOnImeAction() {
val keyboardController = LocalSoftwareKeyboardController.current
var text by rememberSaveable { mutableStateOf("") }
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
// do something here
}
)
)
}