Inzamamur Rahaman
Inzamamur Rahaman

Reputation: 46

how to make Lazy Vertical Staggered Grid's item wrap content

I want my Lazy Vertical Staggered Grid's items to take size of it's content. Contents are of different size.

I want all the item of Lazy Vertical Staggered Grid to display the full text but it's not showing the full text


LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Adaptive(60.dp),
    contentPadding = PaddingValues(12.dp),
    verticalItemSpacing = 8.dp,
    horizontalArrangement = Arrangement.spacedBy(14.dp),
    content = {
        items(state.itemList){item->
        ElevatedCard(shape = AbsoluteRoundedCornerShape(
        topLeft = 16.dp, bottomRight = 16.dp),
        modifier = Modifier.width(IntrinsicSize.Max)
        ) {
         Column(
           modifier = Modifier
                            .padding(8.dp)
        ) {

         Image(
         imageVector = item.icon,
         contentDescription = null,
         colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.inverseSurface),
          modifier = Modifier
            .fillMaxWidth()
            .aspectRatio(4f)
            .clip(RoundedCornerShape(16.dp)),
            )

        Spacer(modifier = Modifier.height(4.dp))

        Text(
        text = item.name,
        maxLines = 1,
        fontFamily = FontFamily.Serif,
        fontWeight = FontWeight.ExtraBold,
        modifier = Modifier
             .align(Alignment.CenterHorizontally)   
        )

        Spacer(modifier = Modifier.height(4.dp))

        Text(
        text = item.pageUrl,
        maxLines = 1,
        fontFamily = FontFamily.Serif,
        fontSize = 12.sp,
        modifier = Modifier.align(Alignment.CenterHorizontally)
        )                   
    }
}

Output I got.

Upvotes: 2

Views: 1392

Answers (2)

Jan Itor
Jan Itor

Reputation: 4216

LazyVerticalStaggeredGrid items are supposed to be the same width but different heights and arranged vertically. If you want different widths, then you can use LazyHorizontalStaggeredGrid, but then items will be arranged horizontally. What are are trying to achieve can be done with a FlowRow instead. Note that the top icon can't have aspectRatio and fillMaxWidth, because increasing width will make it also increase in height.

enter image description here

    FlowRow(
        horizontalArrangement = Arrangement.spacedBy(14.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        itemList.forEach { item ->
            ElevatedCard(
                shape = AbsoluteRoundedCornerShape(
                    topLeft = 16.dp, bottomRight = 16.dp
                ),
                modifier = Modifier.width(IntrinsicSize.Max),
            ) {
                Column(
                    modifier = Modifier
                        .padding(8.dp)
                ) {

                    Image(
                        imageVector = item.icon,
                        contentDescription = null,
                        colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.inverseSurface),
                        modifier = Modifier
                            .fillMaxWidth()
                            //.aspectRatio(4f)
                            .height(12.dp)
                            .clip(RoundedCornerShape(16.dp)),
                    )

                    Spacer(modifier = Modifier.height(4.dp))

                    Text(
                        text = item.name,
                        maxLines = 1,
                        fontFamily = FontFamily.Serif,
                        fontWeight = FontWeight.ExtraBold,
                        modifier = Modifier
                            .align(Alignment.CenterHorizontally)
                    )

                    Spacer(modifier = Modifier.height(4.dp))

                    Text(
                        text = item.pageUrl,
                        maxLines = 1,
                        fontFamily = FontFamily.Serif,
                        fontSize = 12.sp,
                        modifier = Modifier.align(Alignment.CenterHorizontally)
                    )
                }
            }
        }
    }

Upvotes: 3

BenjyTec
BenjyTec

Reputation: 10470

I think the thing that you are trying to achieve does not fit the concept of LazyVerticalStaggeredGrid. See the sample image for LazyVerticalStaggeredGrid below:

http://joebirch.co/android/exploring-lazy-staggered-grids-in-jetpack-compose/

As you can see, the items width is fixed, but the height adjusts depending on the length of the content inside the item. So you can't really set the item width to wrap content. The only thing you could do is to play around with the StaggeredGridCells values. You can increase the minSize value in StaggeredGridCells.Adaptive(60.dp) to increase the item width.

Even if you were able to set the width to wrap content, you should consider that if a user sets the system font size on their phone to very large, it would happen that the whole layout becomes a single column.

So my proposed workaround is, if you really want to use a LazyVerticalStaggeredGrid, increase the min width value

StaggeredGridCells.Adaptive(100.dp)

and then configure the title Text to ellipsize:

Text(
    text = item.name,
    maxLines = 1,
    overflow = TextOverflow.Ellipsis
    fontFamily = FontFamily.Serif,
    fontWeight = FontWeight.ExtraBold,
    modifier = Modifier.align(Alignment.CenterHorizontally)
)

As a possible alternative, please check out the FlowLayout Composables. There, you can set each item width to wrapContentWidth().

Upvotes: 0

Related Questions