Freerk92
Freerk92

Reputation: 75

Jetpack Compose Card UI taking too much space

I'm working on a reference app for Blood Bowl and I can't seem to get the top Card to wrap tighter around the text and integers.

If I remove the IntrinsicSize from the Row the fillMaxHeight of the Column doesn't work. And if I remove the fillMaxHeight from the Column the colored background of the left side won't reach the bottom of the card

The weird thing also being, without the 16dp padding on the last Column, the bottom Card was too small.

Anyone know what I am doing wrong here?

@Composable
fun WeatherCardWithTopBar(title: String, text: String, icon: ImageVector) {
    Card {
        Row(Modifier
            .fillMaxWidth()
            .height(IntrinsicSize.Max),
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth(0.20f)
                    .background(
                        MaterialTheme.colorScheme.secondary,
                    )
                    .padding(8.dp)
                    .fillMaxHeight(),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Icon(
                    imageVector = icon,
                    modifier = Modifier.size(48.dp),
                    contentDescription = "Weather",
                    tint = MaterialTheme.colorScheme.onSecondary,
                )
                Text(
                    text = title,
                    modifier = Modifier.padding(8.dp),
                    style = MaterialTheme.typography.titleLarge,
                    color = MaterialTheme.colorScheme.onSecondary,
                )
            }
            Column(Modifier.padding(16.dp)) {
                Text(text = text)
            }
        }
    }
}

Preview

Edit: @Always_a_Learner this happens on the page if I remove the Intrinsic and fillMaxHeight

What I'm trying to make is to have the weather icon and number to take the full height of the card with a dark background.

Preview2

I fixed it in a roundabout way. I reversed the colors, so the card itself is the darker color, and the column of the text now has a background color for the lighter color. (This might not have been needed) To keep the width of the part with the icon and numbers the same, I put horizontal padding on the icon, because those are all the same width. This ignores the different widths of the numbers (i.e. "2" vs "4-10"). Putting the verticalpadding of this element in the column where it is in. I do still need the IntrinsicSize because otherwise the fillMaxHeight doesn't fill out to the top and bottom of the card

@Composable()
fun WeatherCardWithTopBar(title: String, text: String, icon : ImageVector) {
    Card(

    ) {
        Row(Modifier
            .background(
                MaterialTheme.colorScheme.secondary
            )
            .fillMaxWidth()
            .height(IntrinsicSize.Max),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Column(
                modifier = Modifier
                    .background(
                        MaterialTheme.colorScheme.secondary
                    )
                    .fillMaxHeight()
                    .padding(vertical = 16.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Icon(
                    icon,
                    modifier = Modifier
                        .padding(horizontal = 16.dp)
                        .size(48.dp),
                    contentDescription = "Weather",
                    tint = MaterialTheme.colorScheme.onSecondary
                )
                Text(
                    text = title,
                    modifier = Modifier.padding(8.dp),
                    style = MaterialTheme.typography.titleLarge,
                    color = MaterialTheme.colorScheme.onSecondary
                )
            }
            Column(Modifier
                .background(
                    MaterialTheme.colorScheme.onSecondary
                )
                .fillMaxHeight()
                .padding(16.dp)
            ) {
                Text(text = text)
            }
        }
    }
}

With this code I get the following result:

enter image description here

Upvotes: 1

Views: 60

Answers (2)

Freerk92
Freerk92

Reputation: 75

(Same text as the fix in the question)

I fixed it in a roundabout way.

I reversed the colors, so the card itself is the darker color, and the column of the text now has a background color for the lighter color. (This might not have been needed)

To keep the width of the part with the icon and numbers the same, I put horizontal padding on the icon, because those are all the same width. This ignores the different widths of the numbers (i.e. "2" vs "4-10").

Putting the verticalpadding of this element in the column where it is in.

I do still need the IntrinsicSize because otherwise the fillMaxHeight doesn't fill out to the top and bottom of the card

@Composable()
fun WeatherCardWithTopBar(title: String, text: String, icon : ImageVector) {
    Card(

    ) {
        Row(Modifier
            .background(
                MaterialTheme.colorScheme.secondary
            )
            .fillMaxWidth()
            .height(IntrinsicSize.Max),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Column(
                modifier = Modifier
                    .background(
                        MaterialTheme.colorScheme.secondary
                    )
                    .fillMaxHeight()
                    .padding(vertical = 16.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Icon(
                    icon,
                    modifier = Modifier
                        .padding(horizontal = 16.dp)
                        .size(48.dp),
                    contentDescription = "Weather",
                    tint = MaterialTheme.colorScheme.onSecondary
                )
                Text(
                    text = title,
                    modifier = Modifier.padding(8.dp),
                    style = MaterialTheme.typography.titleLarge,
                    color = MaterialTheme.colorScheme.onSecondary
                )
            }
            Column(Modifier
                .background(
                    MaterialTheme.colorScheme.onSecondary
                )
                .fillMaxHeight()
                .padding(16.dp)
            ) {
                Text(text = text)
            }
        }
    }
}

With this code I get the following result:

AnswerPreview

Upvotes: 0

Gold Yon War
Gold Yon War

Reputation: 29

Not Sure this one can help you. Please take a look. IntrinsicSize.Max can cause unintended behavior in layout calculation, especially with the combination of fillMaxHeight().

@Composable
fun WeatherCardWithTopBar(title: String, text: String, icon: ImageVector) {
    Card(
        modifier = Modifier.padding(8.dp) // External padding to adjust card spacing
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(8.dp), // Internal padding for Row
        ) {
            // Left side column with background and centered content
            Column(
                modifier = Modifier
                    .fillMaxWidth(0.20f)
                    .background(MaterialTheme.colorScheme.secondary)
                    .padding(8.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center, // Center content vertically
            ) {
                Icon(
                    imageVector = icon,
                    modifier = Modifier.size(48.dp),
                    contentDescription = "Weather",
                    tint = MaterialTheme.colorScheme.onSecondary,
                )
                Text(
                    text = title,
                    modifier = Modifier.padding(top = 8.dp), // Adjusted padding for text
                    style = MaterialTheme.typography.titleLarge,
                    color = MaterialTheme.colorScheme.onSecondary,
                )
            }
            // Right side column for additional text
            Column(
                modifier = Modifier
                    .weight(1f) // Fills the remaining width of the Row
                    .padding(start = 16.dp) // Padding between columns
            ) {
                Text(
                    text = text,
                    style = MaterialTheme.typography.bodyMedium,
                )
            }
        }
    }
}

Result: enter image description here

Upvotes: 0

Related Questions