8

I'm using the Jetpack Compose TextField and I want to close the virtual keyboard when the user press the the action button (imeActionPerformed parameter).

val text = +state { "" }
TextField(
    value = text.value,
    keyboardType = KeyboardType.Text,
    imeAction = ImeAction.Done,
    onImeActionPerformed = { 
        // TODO Close the virtual keyboard here <<<
    }
    onValueChange = { s -> text.value = s }
)
azizbekian
  • 53,978
  • 11
  • 145
  • 225
nglauber
  • 2,430
  • 17
  • 22

3 Answers3

22

With the 1.0.0 (tested with 1.0.0-beta07) you can use the LocalSoftwareKeyboardController class:

var text by remember { mutableStateOf(TextFieldValue("Text")) }
val keyboardController = LocalSoftwareKeyboardController.current

TextField(
        value = text,
        onValueChange = {
            text = it
        },
        label = { Text("Label") },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
        keyboardActions = KeyboardActions(
                onDone = {keyboardController?.hide()})
)
Gabriele Mariotti
  • 192,671
  • 57
  • 469
  • 489
9

As of compose version 1.0.0-alpha12 (valid in beta02) the onImeActionPerformed is deprecated and suggested approach is to use keyboardActions with combination of keyboardOptions:

    val focusManager = LocalFocusManager.current

    OutlinedTextField(
        value = ...,
        onValueChange = ...,
        label = ...,
        keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
        keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done, keyboardType = KeyboardType.Password),
    )

focusManager.clearFocus() will take care of dismissing the soft keyboard.

azizbekian
  • 53,978
  • 11
  • 145
  • 225
1

Edit after alpha-12 release: See @azizbekian response.

Pre-alpha-12 response

I found the solution here :)

fun hideKeyboard(activity: Activity) {
    val imm: InputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    var view = activity.currentFocus
    if (view == null) {
        view = View(activity)
    }
    imm.hideSoftInputFromWindow(view.windowToken, 0)
}

I just need to call the function above from my component:

// getting the context
val context = +ambient(ContextAmbient)

// textfield state
val text = +state { "" }

TextField(
    value = text.value,
    keyboardType = KeyboardType.Text,
    imeAction = ImeAction.Done,
    onImeActionPerformed = { 
        if (imeAction == ImeAction.Done) {
            hideKeyboard(context as Activity)
        }
    }
    onValueChange = { s -> text.value = s }
)
nglauber
  • 2,430
  • 17
  • 22