Reputation: 3294
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?
Upvotes: 24
Views: 22902
Reputation: 1
Edit: I was having an issue inside a popup composable where Keyboard was not sliding on focus in the text field
As per the issue on YouTrack Jet Brains you can solve the issue by setting a focusable property in the Popup
Popup(
onDismissRequest = onDismiss,
alignment = Alignment.Center,
properties = PopupProperties(
focusable = true
)
) {
// ....
}
By doing this I'm getting the keyboard on textfield inside the Popup
Upvotes: 0
Reputation: 6863
Here's a quick hack using the View-Based Official Method but we use Compose instead by using the Interoperability API.
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.
And Passing an empty Composable (View) as the parameter:
showSoftKeyboard(AndroidView(context))
Upvotes: -12
Reputation: 1300
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),
)
Upvotes: 2
Reputation: 300
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()
}
Upvotes: 15
Reputation: 546
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)...)
Upvotes: -1
Reputation: 471
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()
}
}
}
Upvotes: 23
Reputation: 210
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
.
Upvotes: 2
Reputation: 1042
To show keyboard in Compose:
val showKeyboard = remember { mutableStateOf(true) }
val focusRequester = remember { FocusRequester() }
val keyboard = LocalSoftwareKeyboardController.current
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = value,
textStyle = MaterialTheme.typography.body2,
onValueChange = { onValueChange(it)},
label = { Text(label) }
)
// LaunchedEffect prevents endless focus request
LaunchedEffect(focusRequester) {
if (showKeyboard.equals(true)) {
focusRequester.requestFocus()
delay(100) // Make sure you have delay here
keyboard?.show()
}
}
Upvotes: 32