Rainmaker
Rainmaker

Reputation: 11090

Android Compose show and hide keyboard

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?

Upvotes: 4

Views: 12054

Answers (3)

David Sucharda
David Sucharda

Reputation: 51

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.

Upvotes: 1

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363507

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.

Upvotes: 17

peresisUser
peresisUser

Reputation: 1686

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

Upvotes: 0

Related Questions