4

I have a composable function with TextField:

val focusManager = LocalFocusManager.current
TextField(
        keyboardOptions = KeyboardOptions.Default.copy(
            imeAction = ImeAction.Search,
        ),
        keyboardActions = KeyboardActions(
            onSearch = {
                focusManager.clearFocus()
            }
        )
    )

and I need to show keyboard from inside of composable function as well as outside of it when I click on other button which is not part of composable content. Basically I wanna call hideKeyboard() from my fragment.

I tried to use livedata inside composable:

val shouldShowKeyBoard by shouldShowSearchKeyBoard.observeAsState()

and I can do focusManager.clearFocus() to hide keyboard but I'm not sure how to show it programmatically for specific compose TextField

What's the "compose" way to manage hide/show keyboard?

Rainmaker
  • 10,294
  • 9
  • 54
  • 89

3 Answers3

15

You can perform some action on state changes and you can do it using the side effects.
For example you can use the LaunchedEffect function, where as a key you can pass a state you want to listen.

LaunchedEffect(booleanValue) {
    //...do something
}

You can use a ViewModel to set a boolean value and something like:

// initialize focus reference to be able to request focus programmatically
val focusRequester = remember { FocusRequester() }
LaunchedEffect(viewModel.showKeyboard) {
    focusRequester.requestFocus()
}

TextField(
    value = text,
    onValueChange = {
        text = it },
    modifier = Modifier
        // add focusRequester modifier
        .focusRequester(focusRequester)
)

Just a note: to hide the keyboard you can also use:

   val keyboardController = LocalSoftwareKeyboardController.current

   TextField(
     //...
     keyboardActions = KeyboardActions(
        onSearch = { keyboardController?.hide() }
    )

Use the method focusManager.clearFocus() to dismiss the keyboard and clear the focus.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • Working solution Thanks @Gabriele Can you help me out on this: https://stackoverflow.com/questions/73650798/how-pass-parcelable-object-with-new-version-of-compose-navigation?noredirect=1#comment130059237_73650798 – InsaneCat Sep 09 '22 at 07:40
1

There is also an option to use the default keyboard action after your own action. I have a search TextField which on Done click triggers the search function and then hides the keyboard. I achieved keyboard hiding with calling this.defaultKeyboardAction(ImeAction.Done) after my action.

SearchTextField(
    textFieldState = searchState,
    placeholder = stringResource(R.string.common_search),
    keyboardActions = KeyboardActions(onDone = {
        onSearchDone()
        this.defaultKeyboardAction(ImeAction.Done) <-- This hides the keyboard
    })
)

With a search action it would have to be like this:

SearchTextField(
    textFieldState = searchState,
    placeholder = stringResource(R.string.common_search),
    imeAction = ImeAction.Search,
    keyboardActions = KeyboardActions(onSearch = {
        onSearchDone()
        this.defaultKeyboardAction(ImeAction.Done)
    })
)

ImeAction.Search does not hide the keyboard but the done action does.

0

to add on Gabriele's answer, you will need val focusRequester = remember { FocusRequester() } or you will get an exception

peresisUser
  • 1,680
  • 18
  • 23