Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Force Jetpack Compose to display 2 Text() Components one below other

Hi I have such piece of code: it draws movie card. The problem, which I have, is that only one of two Text components are printed. I tried many versions of modifications, but always there is only one text. Could you explain me why? 🙁

item {
    key(movie.id) {
        Box(contentAlignment = Alignment.CenterStart) {
            StandardCardLayout(
                modifier = Modifier
                    .aspectRatio(1.25f)
                    .padding(8.dp)
                    .then(
                        if (index == 0)
                            Modifier.focusOnInitialVisibility(isFirstItemVisible)
                        else Modifier
                    ),
                imageCard = {
                    CardLayoutDefaults.ImageCard(
                        shape = CardDefaults.shape(shape = JetStreamCardShape),
                        border = CardDefaults.border(
                            focusedBorder = Border(
                                border = BorderStroke(
                                    width = JetStreamBorderWidth,
                                    color = MaterialTheme.colorScheme.onSurface
                                ),
                                shape = JetStreamCardShape
                            ),
                            pressedBorder = Border(
                                border = BorderStroke(
                                    width = JetStreamBorderWidth,
                                    color = MaterialTheme.colorScheme.border
                                ),
                                shape = JetStreamCardShape
                            ),
                        ),
                        scale = CardDefaults.scale(focusedScale = 1f),
                        onClick = { onMovieSelected(movie) },
                        interactionSource = it
                    ) {
                        AsyncImage(
                            model = ImageRequest.Builder(LocalContext.current)
                                .data(movie.posterUri)
                                .crossfade(true)
                                .build(),
                            contentDescription = StringConstants
                                .Composable
                                .ContentDescription
                                .moviePoster(movie.name),
                            contentScale = ContentScale.Crop,
                            modifier = Modifier.fillMaxWidth().aspectRatio(1.77f)
                        )
                        Text(
                            text = movie.name.take(20),
                            style = MaterialTheme.typography.bodySmall.copy(
                                fontWeight = FontWeight.SemiBold,
                                lineHeight = 2.em
                            ),
                            textAlign = TextAlign.Center,
                            modifier = modifier
//                                                .alpha(1f)
                                .fillMaxWidth()
                                .wrapContentHeight(align = Alignment.Top, unbounded = true)
//                                                .padding(top = 26.dp)
                                .background(color = Color.Black)
                                .align(Alignment.TopCenter)
                            ,
                            maxLines = 2,
                            overflow = TextOverflow.Ellipsis,
                            color = Color.White,
                            lineHeight = 15.sp,
                            fontSize = 10.sp,
                        )
                        Text(
                            text = "(${movie.stars}) " + movie.releaseDate,
                            style = MaterialTheme.typography.bodySmall.copy(
                                fontWeight = FontWeight.SemiBold
                            ),
                            textAlign = TextAlign.Center,
                            modifier = modifier
//                                                .alpha(1f)
                                .fillMaxWidth()
                                .wrapContentHeight(align = Alignment.Top, unbounded = true)
//                                                .padding(top = 26.dp)
                                .background(color = Color.Black)
                                .align(Alignment.BottomCenter)
                            ,
                            maxLines = 2,
                            overflow = TextOverflow.Ellipsis,
                            color = Color.White,
                            lineHeight = 15.sp,
                            fontSize = 10.sp
                        )
                    }
                },
                title = {},
            )
        }
    }
}

I tried to use:

Modifier.wrapContentHeight
Modifier.height
Modifier.aspectRatio
lineHeight
etc...

Preview on single ‘item’

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

As you can see on the image, it prints only one text.
I know, that I could print it with "\n" escape sequence, and use one Text component, but I need different styles for each text.

EDIT:
My layout is:

Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxHeight()
    ) {
        TvLazyVerticalGrid(
            columns = TvGridCells.Fixed(4),
            contentPadding = PaddingValues(
                bottom = JetStreamBottomListPadding,
//                horizontal = 16.dp, vertical = 8.dp
            ),
            state = gridState,
            modifier = modifier
        ) {
...
movieList.forEachIndexed { index, movie ->
    item {
        key(movie.id) {
            Box(contentAlignment = Alignment.CenterStart) {

EDIT2:

Ok, thanks, I’ve found, I had .fillMaxHeigh() in external component execution.

>Solution :

It all depends on what CardLayoutDefaults.ImageCard does with the content that is provided for its last parameter. Despite the name it doesn’t seem to use a specific strategy to layout its children, so all children (that is the AsyncImage and two Texts) are placed on top of each other.

That can easily be fixed by providing your own layout component. It can be placed either inside CardLayoutDefaults.ImageCard wrapping the content or directly in the code from your example wrapping the three elements.

If the elements should be arranged vertically you should use a Column as layout component. If they should be arranged horizontally, wrap them in a Row. There are more layouts available. See the documentation if you want to learn more about layouts.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading