How to edit a TextField from two different sources?

Viewed 45

I have a simple app written in Compose, which asks the user a question, and they have to provide the answer in a text field. There's also a "hint" button, which when clicked, will populate the text field with the next character of the correct answer.

Let's assume the correct answer here is "Leonardo da Vinci".

All is well, until I click the "Hint" button enough times, so that I am hinted with a space, so for example I get Leonardo , and then start typing the rest of the answer on the soft keyboard. The hinted characters disappear for some reason!

enter image description here

This also happens only on my Pixel 5, Android 12 device, but not on a Samsung Galaxy S21, Android 11, for example.

I understand that this has to do with the composition property on the TextFieldValue, but we're discouraged from editing it it seems.

On the Pixel, I can see that the composition changes depending on what part of the phrase is underlined, but on the Samsung, it's always null, so even if I wanted to I'm not able to control it reliably across devices :(

Here's the composable (styling omitted):

@Composable
fun TextFieldWithHints(correctAnswer: String) {

    var textFieldValue by remember {
        mutableStateOf(TextFieldValue())
    }

    Column {
        BasicTextField(
            value = textFieldValue,
            onValueChange = { newTextFieldValue ->
                textFieldValue = newTextFieldValue
            }
        )

        Button(
            onClick = {
                val currentAnswerLength = textFieldValue.text.length
                val nextCharacterToHint = correctAnswer[max(0, currentAnswerLength)]
                val newAnswer = textFieldValue.text + nextCharacterToHint

                //here's where I update the current answer with a hint
                textFieldValue = textFieldValue.copy(text = textFieldValue.text + nextCharacterToHint, selection = TextRange(newAnswer.length))
            },
        ) {
            Text(text = "Hint!")
        }
    }
}

PS. I'm using a TextFieldValue because I need to control the selection property as well - which is how you tell the cursor where to go

0 Answers
Related