How to show the software keyboard on composition (i.e. when a screen composable is first displayed)?
j
How to show the software keyboard on composition (i.e. when a screen composable is first displayed)?
Copy code
val keyboardController = LocalSoftwareKeyboardController.current
SideEffect {
    keyboardController?.show()
}
This code doesn’t seem to make it happen.
f
Well
SideEffect
is triggered for every recomposition so I would use either
LaunchedEffect
or
DisposableEffect
. Basically any effect with key. The reason this is not ideal is that doing something on the first render of composable is suspicious and probably should be done elsewhere like ViewModel. There were several discussions around this topic if I recall correctly.
j
Copy code
val keyboardController = LocalSoftwareKeyboardController.current
DisposableEffect(null) {
    keyboardController?.show()
    onDispose {}
}
Doesn’t work either
f
And by "does not work" you mean that the keyboard won't show at all?
👌 1
j
It’s okay to do it “somewhere else”, but where? I’m using compose-navigation so this screen composable is launched by the
NavHost
.
f
Reading the documentation, do you have a TextField or similar on the screen?
The software keyboard will never show if there is no composable that will accept text input, such as a TextField when it is focused. You may find it useful to ensure focus when calling this function.
j
Doing it from a ViewHolder or Activity means I’d have to use old fashioned APIs, which is what I was trying to avoid. Moreover doing it at the activity level would be not ideal because the goal was to show the keyboard only when navigating to a certain screen.
Yepp, I put a
TextField
in the screen on purpose
Copy code
val focusRequester = FocusRequester()
DisposableEffect(null) {
    focusRequester.requestFocus()
    onDispose {}
}
var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    modifier = Modifier.focusRequester(focusRequester)
)
This did it 🤷
f
Hmmm, it seems that the TextField has to be actually focused for it to work.
Yeah, was just about to propose it 😄
j
No need for LocalSoftwareKeyboardController either 🤷 🤷 🤷
f
If you look at the implementation of the show method, it calls
textInputService.showSoftwareKeybord()
and it says:
Request showing onscreen keyboard.
This call will be ignored if there is not an open TextInputSession, as it means there is nothing that will accept typed input. The most common way to open a TextInputSession is to set the focus to an editable text composable.
So you would need to focus the TextField anyway. This API seems to be for opening keyboard for components that can't do it themselves and we would have to focus them first.
👌 1
I think that the
LocalSoftwareKeyboardController
was meant more for closing the keyboard rather than opening it 😄
👌 1
a
cc @Sean McQuillan [G]
s
Yea, a TextField has to be focused to work - you should get the effect you want just by setting the focus
The SoftwareKeyboardController only needs used if you've manually hidden it or are building your own textfield-like thing, focus on BasicTextField causes keybord hide/show as an intrinsic behaviror
@julioromano what parts of the documentation had you read when you were trying to use software keyboard controller. I'd like to catch the path you went down and make sure it's clear.
j
@Sean McQuillan [G] no doc brought me here specifically. I was trying to show the software keyboard when the only text input on screen was inside an
AndroidView
and run out of ideas. So I tried
SoftwareKeyboardController
and
FocusRequester
too (without success tho). Ref: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1617831016388200
l
The SoftwareKeyboardController only needs used if you've manually hidden it or are building your own textfield-like thing, focus on BasicTextField causes keybord hide/show as an intrinsic behaviror
Can it be customized ? For example when user click somewhere else of the BasicTextField the focus is removed which dismiss the keyboard. In one of my use case, I would like to avoid this behaviour. Is it possible ?
s
Lucien, no you have to retain focus on editable text to show the keyboard as an intentional choice: • This is the expected platform behavior and deviations will appear as bugs to the user • When no text is editable, the keyboards suggestions behavior appears as a bug (e.g. clicking a word has no effect, the word stays) • Performing an edit operation as a user has no effect, which is likely to be perceived as a bug
Your best bet in TextField level APIs is to ensure that a textfield is focused. If you can't and really need the behavior and want to hop down a level you can open a input connection yourself using
TextInputService
and it'll be automatically closed when the next
TextField
gets focus.
l
Sorry I might have had a bad explanation of my need. Here is the context: I have a HomeView with a search (a customized BasicTextField) on top screen and a list under this search. When the search (so the BasicTextField) is focused a Composable is shown on top of the previous list (using AnimatedVisibility, the visble parameter being the focus value of the search). So here what I would like, is to avoid the click on elsewhere of the search to set the focus to false. I want the BasicTextField stay focused for this behaviour (I have a back button and I'm using keyboardActions to handle this manually)
s
You should be able to do this with the focus requester API and onFocusChanged (basically just never let it become unfocused)
(I'm not an expert on the focus APIs so if there's a better way lmk 🙂 )
l
Ok thanks, I will take a look at these API :)
485 Views