androidkotlinandroid-jetpack-compose

Last composables in Row() get squeezed (Jetpack Compose)


I am trying to create a custom search bar; in which I am using Row() composable as a container for all the other elements. Here the last FloatingActionButton gets squeezed but I want the TextField to be flexible so that it gets shortened to accommodate the remaining elements.

Last element squeezed in Row

I already know some workarounds to this but I want a better solution. See below for the known workarounds and their drawbacks.


@Preview(showBackground = true, widthDp = 410)
@Composable
fun MyComposable() {
    Row(Modifier.fillMaxWidth()) {
        TextField(value = "Search", onValueChange = {})
        FloatingActionButton(onClick = {}) {Icon(Icons.Filled.SkipNext, contentDescription = null)}
        FloatingActionButton(onClick = {}) {Icon(Icons.Filled.Close, contentDescription = null)}
        FloatingActionButton(onClick = {}) {Icon(Icons.Filled.Home, contentDescription = null)}
    }
}

Known workarounds:

  1. Using ConstraintLayout (Drawback: Complicated. Seems like overkill in many situations.)
  2. Using CompositionLocalProvider to provide a RTL LocalLayoutDirection. (Drawback: Seems hacky. All the layouts of child components become RTL. For example textfield icons and text placement.)
  3. Specifying fixed width (or weights) to the last element. (Drawback: This makes the second last element to squeeze and forces me to hardcode width which cannot be done on some elements like Button as its width is determined by localized text in it.)

Solution

  • You can apply the weight(1f) to the TextField:

    Row(Modifier.fillMaxWidth()) {
            TextField(
                modifier = Modifier.weight(1f),
                value = "Search", onValueChange = {})
    
            FloatingActionButton(onClick = {}) {Icon(Icons.Filled.SkipNext, contentDescription = null)}
            FloatingActionButton(onClick = {}) {Icon(Icons.Filled.Close, contentDescription = null)}
            FloatingActionButton(onClick = {}) {Icon(Icons.Filled.Home, contentDescription = null)}
        }
    

    enter image description here enter image description here