How can I slide in the keyboard? I tried:
val keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current
keyboardController?.show()
But it does not work. What am I missing? Maybe some Manifest flags?
How can I slide in the keyboard? I tried:
val keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current
keyboardController?.show()
But it does not work. What am I missing? Maybe some Manifest flags?
What's the issue with the official method?
fun showSoftKeyboard(view: View) {
if (view.requestFocus()) {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
}
Read more here.
This method works if you just use it like this:
showSoftKeyboard(AndroidView(context))
You could also try eliminating the parameter entirely by placing the AndroidView
in the function's body instead.
The following works fine when it is needed to show keyboard for an edit when scene is opened:
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) { focusRequester.requestFocus() }
TextField(
...
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
)
For my use case, I needed the keyboard to be shown when there is a bottom sheet shown with the editText. The accepted answer works for the first time and then stops working if the user switches to a different app for some time (interruptions). So I combined the above solution with a lifecycle event to trigger the keyboard when the view is actually visible to the user.
fun SomeView(lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current) {
val focusRequester = remember { FocusRequester() }
val keyboard = LocalSoftwareKeyboardController.current
val scope = rememberCoroutineScope()
DisposableEffect(key1 = lifecycleOwner, effect = {
val observer = LifecycleEventObserver { _, event ->
scope.launch {
if (event == Lifecycle.Event.ON_RESUME) {
focusRequester.requestFocus()
awaitFrame()
keyboard?.show()
}
}
}
// Add the observer to the lifecycle
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
})
TextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = "",
onValueChange = {},
placeholder = { Text(text = "New Note") },
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
)
)
The above adds a lifecycle observer and triggers the Keyboard show when the lifecycle event is ON_RESUME
.
I am currently using the compose BOM version 2023.05.01
.
The other answers did not work for me. However, I did manage to get it to work when I changed the LaunchedEffect from the accepted answer. With the following code snippet, the software keyboard opens and you can start typing inside of the textfield.
val focusRequester = remember { FocusRequester() }
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = value,
textStyle = MaterialTheme.typography.body2,
onValueChange = { onValueChange(it)},
label = { Text(label) }
)
LaunchedEffect(focusRequester) {
awaitFrame()
focusRequester.requestFocus()
}
delay
is not a robust way to show a keyboard. Keyboard is not shown because the window is not focused yet in most cases. The solution would be like this:
val windowInfo = LocalWindowInfo.current
val focusRequester = remember { FocusRequester() }
TextField(modifier = Modifier.focusRequester(focusRequester)...)
LaunchedEffect(windowInfo) {
snapshotFlow { windowInfo.isWindowFocused }.collect { isWindowFocused ->
if (isWindowFocused) {
focusRequester.requestFocus()
}
}
}
The answer from Leon Wu https://stackoverflow.com/a/75985103/4908512 seems to be the best one. For my use case, it was better to put request focus in a side effect.
val focusRequester = remember {
FocusRequester()
}
var queryText by remember(query) { mutableStateOf(query) }
val scope = rememberCoroutineScope()
val windowInfo = LocalWindowInfo.current
SideEffect {
scope.launch {
snapshotFlow { windowInfo.isWindowFocused }.collect { isWindowFocused ->
if (isWindowFocused && requestFocus) {
focusRequester.requestFocus()
}
}
}
}
TextField(modifier = Modifier.focusRequester(focusRequester)...)
To show keyboard in Compose: