6

I want to make a simple jetpack compose layout, using weights. below is the code

Row() {
Column(
    Modifier.weight(1f).background(Blue)){
    Text(text = "Weight = 1", color = Color.White)
}
Column(
    Modifier.weight(2f).background(Yellow)
) {
    Text(text = "Weight = 2")
}
}

which will result in a layout like this Simple row column lauout using weights.

but what if my inner views are coming from some other Composable function, which is unaware that its going to be a child of a column or a row?

Row() {
  // Calling Some composable function here
}

In that case i am not able to access the Modifier.weight(..) function, because it thinks that its not in the row or column scope, because it is an independent function.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Bharat Kumar
  • 806
  • 14
  • 22

3 Answers3

6

You can add the modifier as parameter in your Composable.

Something like:

@Composable
fun myCard(modifier: Modifier = Modifier, name:String){
    Box(modifier){
            Text(name,textAlign = TextAlign.Center,)
    }
}

In this way the myCard is unaware that its going to be a child of a Column or a Row.

Then in your implementation you can use:

Row(Modifier.padding(16.dp).height(50.dp)) {
    myCard(Modifier.weight(1f).background(Color.Yellow),"Weight = 1")
    myCard(Modifier.weight(2f).background(Color.Red),"Weight = 2")
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • 1
    Thanks for answer, its working. but is there any alternative way? if we don't want to send modifier as a parameter? @gabriele-mariotti – Bharat Kumar Apr 30 '21 at 10:04
6

You can prefix RowScope. or ColumnScope. to your function declaration

@Composable
fun RowScope.SomeComposable() {
    // weights should work in here
    Column(Modifier.weight(1f)){ /**/ }

}
Jarrod Moldrich
  • 405
  • 5
  • 6
0
Row(
                modifier = mainRowModifier,
                verticalAlignment = rowCenterVerticallyAlign
            ) {
                Row(
                    verticalAlignment = rowCenterVerticallyAlign,
                    horizontalArrangement = rowContentArrangementCenter,
                    modifier = Modifier.weight(.5f, true).wrapContentHeight()
                ) {
                    Text(
                        text = "971",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        textAlign = TextAlign.Center
                    )
                    Icon(
                        painter = painterResource(id = resIdDropDownIcon),
                        contentDescription = null,
                        modifier = Modifier.padding(start = startPaddingDropdownIcon.dp)
                    )
                }

                Divider(
                    color = dividerColor,
                    modifier = dividerModifier
                )

                SimpleTextField(
                    modifier = Modifier.weight(2f),
                    value = "",
                    placeHolder = textFieldPlaceholder,
                    keyboardType = KeyboardType.Phone,
                    singleLine = true
                )

                Text(
                    text = optionalTextTxt,
                    modifier = Modifier.weight(.5f, true),
                    style = MaterialTheme.typography.bodySmall,
                    fontSize = optionalTextFontSize.sp
                )
            }

no weight is issue to main row, then i will assign subrow weight to 0.5 and for textField weight will be 2f and last textview weight is issue to 0.5f

then Output will be looks like enter image description here

Qamar khan
  • 179
  • 1
  • 7