0

I'm building a DropDownMenu and the composable showing the current selected item is a TextField. I would like for the text to be resized if the selected element is too long, but I can't seem to find a way do so. I've searched how to autoresize in Jetpack Compose, but every solution I've found requires to know when the text has overflown, which is something I can't seem to do using TextField. In fact, every solution uses Text or BasicTextField, both of which have the onTextLayout option, but no one is using TextField, which has no onTextLayout option. Note that I cannot change composable because TextField has the trailingIcon option which is useful in my case.

ultrapoci
  • 93
  • 1
  • 5

1 Answers1

0

Not sure if I understand the problem correctly, but I hope this solution will help. We can set the options to select as a hashmap of strings and their widths. If the fontSize of your Text composables and the TextField are the same, you can easily calculate width of each string on screen using the onGloballyPositioned() extension for a Modifier.

val selectionOptions = mutableMapOf(
    "Short" to 0.dp,
    "A longer text" to 0.dp,
    "Some very, very long text" to 0.dp
)
val density = LocalDensity.current
val selectedItem = remember { mutableStateOf("") }
val textFieldWidth = remember { mutableStateOf(10.dp) }
Column(
    Modifier
        .padding(top = 100.dp, start = 30.dp, end = 30.dp)
) {
    selectionOptions.forEach {
        Text(
            text = it.key,
            modifier = Modifier
                .clickable {
                    selectedItem.value = it.key
                    textFieldWidth.value = it.value
                }
                .onGloballyPositioned { coordinates ->
                    // assign width to each option in the map
                    selectionOptions[it.key] = with(density) {
                        coordinates.boundsInParent().width.toDp()
                    }
                }
        )
    }
    TextField(
        value = selectedItem.value,
        onValueChange = { value -> selectedItem.value = value },
        modifier = Modifier
            .width(textFieldWidth.value + 40.dp)
            .defaultMinSize(
                minWidth = 0.dp,
                minHeight = TextFieldDefaults.MinHeight
            )
    )
}

It is not an elegant implementation, but I think it is fairly simple. Check out the screen recording to see whether it's what you want: https://drive.google.com/file/d/1VoBuS5XV15UqBOeIoiCult8JxsmF5S4d/view?usp=sharing