'How to call keypress event programmatically for TextField using jetpack compose, android?

When user type in TextField it will call onValueChange{} callback. but when we set the value in TextField the onValueChange{} callback will not call.

I found https://issuetracker.google.com/issues/172239032 open issue.

Below is a code snippet where I have defined TextField.

OutlinedTextField(
        value = enteredValues[index],
        onValueChange = { value: String ->
            onTextFieldValueChange(value)
        },
        singleLine = true,
        keyboardOptions = keyboardOption,
        colors = textFieldColors,
    )

To get the callback of onValueChange I want to call the keypress event programmatically so might be I will get onValueChange callback. Can anyone give me a solution? how to use keypress programmatically in jetpack compose?



Solution 1:[1]

I have no idea why you want to do this, but here it is a suggestion/workaround...

You can simulate the key event like below (credit for this answer):

fun simulateKeyPress(context: Context, key: Int) {
    val a = context as Activity
    a.window.decorView.rootView
    val inputConnection = BaseInputConnection(
        a.window.decorView.rootView,
        true
    )
    val downEvent = KeyEvent(KeyEvent.ACTION_DOWN, key)
    val upEvent = KeyEvent(KeyEvent.ACTION_UP, key)
    inputConnection.sendKeyEvent(downEvent)
    inputConnection.sendKeyEvent(upEvent)
}

Then, you can call this function passing the key code you want to send...

@Composable
fun SimulateKeySender() {
    var text by remember {
        mutableStateOf("")
    }
    val context = LocalContext.current
    val focusRequester = remember {
        FocusRequester()
    }
    Column {
        Button(
            onClick = { simulateKeyPress(context, KeyEvent.KEYCODE_A) }
        ) {
            Text(text = "Send A")
        }
        TextField(
            value = text,
            onValueChange = { text = it },
            modifier = Modifier.focusRequester(focusRequester)
        )
    }
    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }
}

Notice that will only work if the TextField has focus, this is why I'm using the FocusRequester.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nglauber