5

When creating an Android app, I put some Composables in a Row of a Card, as shown below, and it did not work as I expected. The Composable that I put "weight(1f)" on was no longer showing up.

data class Test(
    val title: String,
    val text: String
)

@Composable
fun CardRowSample(
    modifier: Modifier = Modifier,
) {
    val testList =
        listOf(
            Test("AAAA", "1,2,3,4,5,6,7,8,9,10"),
            Test("BBBB", "11,12,13,14,15,16,17,18,19,20")
        )

    LazyColumn(
        modifier = modifier
    ) {
         items(
             items = testList
         ) {
             test ->
                Card(
                    elevation = 12.dp,
                    backgroundColor = Color.LightGray,
                    modifier = Modifier
                        .fillMaxWidth()
                        .heightIn(min = 50.dp)
                        .width(40.dp)
                        .requiredHeight(intrinsicSize = IntrinsicSize.Min)
                        .padding(
                            horizontal = 20.dp,
                            vertical = 20.dp
                        )
                        .border(
                            width = 1.dp,
                            color = Color.Black,
                            shape = RectangleShape
                        )
                ) {
                    Row(
                        modifier = Modifier.fillMaxWidth()
                    ) {

                        Icon(
                            modifier = Modifier
                                .padding(horizontal = 5.dp)
                                .align(Alignment.CenterVertically),
                            imageVector = Icons.Filled.Check,
                            contentDescription = null
                        )

                        Text(
                            text = test.title,
                            fontSize = 20.sp,
                            modifier =
                            Modifier
                                .width(120.dp)
                                .padding(horizontal = 10.dp, vertical = 10.dp)
                        )

                        Text(
                            text = test.text,
                            fontSize = 20.sp,
                            modifier = Modifier
                                .weight(1f)//it doesn't work!!
                                .padding(horizontal = 10.dp, vertical = 10.dp)
                        )
                    }
                }
        }
    }
}

enter image description here


My ideal image of the layout:

enter image description here


I wrote the code referring to the following question, Weights in Jetpack compose, but I can't figure out why this is happening. I put "weight" on everything and added fillParentMaxSize to the Row's modifier, but I wasn't able to solve this problem.

What should I do next to solve this problem?

tofu
  • 141
  • 5
  • 1
    Try Removing `width` and `requiredHeight` attributes from Card Composable . And make your Row fill mas Size with `verticalAlignment = Alignment.CenterVertically`. – ADM Sep 08 '22 at 04:46

2 Answers2

3

Problem is not with Modifier.weight(1f). It's because of Modifier.requiredHeight(IntrinsicSize.Min)

Card(
    elevation = 12.dp,
    backgroundColor = Color.LightGray,
    modifier = Modifier
        .fillMaxWidth()
        .heightIn(min = 50.dp)
//                    .width(40.dp)
//                    .requiredHeight(intrinsicSize = IntrinsicSize.Min)
        .padding(
            horizontal = 20.dp,
            vertical = 20.dp
        )
        .border(
            width = 1.dp,
            color = Color.Black,
            shape = RectangleShape
        )
) 

Also Modifier.width(40.dp) is redundant because you have another width modifier Modifier.fillMaxWidth() before that.

When Modifier.requiredIn with Intrinsic size modifiers act strange. Composable gets measured twice and with Infinity constraints

LAYOUT constraints: Constraints(minWidth = 0, maxWidth = 1080, minHeight = 0, maxHeight = Infinity), width: 1080, height: 235
LAYOUT constraints: Constraints(minWidth = 0, maxWidth = Infinity, minHeight = 235, maxHeight = 235), width: 510, height: 235

That's the second measurement breaks width because of maxWidth = Infinity. 1080px is full width on my device

to see Constrains and Composable width and height you can use

Card(
    elevation = 12.dp,
    backgroundColor = Color.LightGray,
    modifier = Modifier
        .fillMaxWidth()
        .heightIn(min = 50.dp)
//                    .width(40.dp)
                    .requiredHeight(intrinsicSize = IntrinsicSize.Min)
        .layout { measurable, constraints ->
            val placeable = measurable.measure(constraints)
            println("LAYOUT constraints: $constraints, width: ${placeable.width}, height: ${placeable.height}")
            layout(placeable.width,placeable.height){
                placeable.placeRelative(0,0)
            }
        }
        .padding(
            horizontal = 20.dp,
            vertical = 20.dp
        )
        .border(
            width = 1.dp,
            color = Color.Black,
            shape = RectangleShape
        )
) 
Thracian
  • 43,021
  • 16
  • 133
  • 222
  • I have no idea why it happens though with required and Intrinsic combined. If you change to `height(intrinsicSize = IntrinsicSize.Min)` you get `Constraints(minWidth = 1080, maxWidth = 1080, minHeight = 235, maxHeight = 235)` and full width. Intrinsic sizes call layout twice but why with Infinity when requiredHeight is set i have no clue – Thracian Sep 08 '22 at 05:03
1

An alternative to the Thracian's answer is to apply Modifier.height(IntrinsicSize.Min) to your Card and fillMaxHeight() to the Icon.

    Card(
        elevation = 12.dp,
        backgroundColor = Color.LightGray,
        modifier = Modifier
            .fillMaxWidth()
            .heightIn(min = 50.dp)
            .height(intrinsicSize = IntrinsicSize.Min)
            .padding(
                horizontal = 20.dp,
                vertical = 20.dp
            )
            .border(
                width = 1.dp,
                color = Color.Black,
                shape = RectangleShape
            )
    ) {
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {

            Icon(
                modifier = Modifier
                    .fillMaxHeight()
                    .padding(horizontal = 5.dp)
                    .align(Alignment.CenterVertically),
                imageVector = Icons.Filled.Check,
                contentDescription = null
            )

            Text(
                text = test.title,
                fontSize = 20.sp,
                modifier =
                Modifier
                    .width(120.dp)
                    .padding(horizontal = 10.dp, vertical = 10.dp)
            )

            Text(
                text = test.text,
                fontSize = 20.sp,
                modifier = Modifier
                    .weight(1f)
                    .padding(horizontal = 10.dp, vertical = 10.dp)
            )
        }
    }
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841