9

I want to set RadioButton component at the end of Row in Jetpack Compose. Tried to using Constraint Layout and moved RadioButton outside the Row but then the RadioButton wasn't centered with other components in Row. What should I do? enter image description here

Here is my code:

    ConstraintLayout {
        val (row, button) = createRefs()
        Row(
            modifier = Modifier
                .height(56.dp)
                .fillMaxWidth()
                .constrainAs(row){
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                },
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(
                /* *** */
            )
            Text(
                text = "mail@gmail.com",
                modifier = Modifier.padding(start = 16.dp, end = 16.dp),
            )
            RadioButton(
                /* *** */
            )
        }

    }

What is more i want to cut the Text component if the text is too long (not overlay or underlay the Radio Button)

AndroideuszPL
  • 385
  • 1
  • 2
  • 13

1 Answers1

29

The simplest solution would be to add a Spacer with Modifier.weight(1f) between your text and the radio button. Row and Column distribute remaining available space between components with a weight Modifier according to their weight. Since there is only one, it will receive all of the remaining space, pushing the radio button to the far right.

For example following code would produce your desired behavior:


Row(modifier = Modifier.height(56.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically){
    Icon(Icons.Default.Add,null)
    Text("Some text here")
    Spacer(Modifier.weight(1f).fillMaxHeight().background(Color.Green)) // height and background only for demonstration
    RadioButton(selected = false, onClick = { /*TODO*/ })
}

enter image description here

As I said remaining space is distributed according to the weight of each element, so although this is not what you want to achieve, an example how this might look like

Row(modifier = Modifier.height(56.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
    Icon(Icons.Default.Add, null)
    Spacer(Modifier.weight(1f).fillMaxHeight().background(Color.Red)) // height and background only for demonstration
    Text("Some text here")
    Spacer(Modifier.weight(4f).fillMaxHeight().background(Color.Green)) // height and background only for demonstration
    RadioButton(selected = false, onClick = { /*TODO*/ })
}

will get you

enter image description here

The remaining space after measuring the icon, text and radio button are distributed as 20% to the red Spacer and 80% to the green one, since that is their share of the total weight (1/5 and 4/5)

Adrian K
  • 3,942
  • 12
  • 15
  • 1
    Unfortunately, after using this solution, the buttons are not positioned in one line (depending on the length of the text) – AndroideuszPL Mar 24 '22 at 08:34
  • @AndroideuszPL Constrain the text to be single line – Blundell Jul 11 '23 at 15:30
  • 2
    No need for a spacer. Add the appropriate paddings to the start and end items in the row. Then add the Weight(1f) modifier to the Text composable itself. The Text is left aligned and will wrap by default, and the weight will cause it to occupy any remaining space in the Row so the length of the text won't affect the overall layout. All the leading icons and Radiobuttons will then have identical spacing and alignment. – Alex Conner Jul 20 '23 at 14:13