Search code examples
android-layoutgridviewandroid-jetpack-composeandroid-jetpack

Achieve Vertical Grid View in Jetpack Compose


My Code :::

@Composable
fun VerticalImageCards(toolsList: List<HealthTool>) {
    val domainName = stringResource(id = R.string.media_url)

    FlowRow(mainAxisSpacing = 8.dp,
        crossAxisSpacing = 16.dp,
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 16.dp),
        mainAxisSize = SizeMode.Wrap) {
        for (i in toolsList) {
            val imgUrl = "$domainName${i.url}"
            ToolsCardLayout(cardTitle = i.title, imgUrl = imgUrl)
        }
    }
}
@Composable
fun ToolsCardLayout(
    imgUrl: String,
    cardTitle: String,
) {
    Box(modifier = Modifier.clickable {}) {
        AsyncImage(model = imgUrl,
            contentDescription = null,
            contentScale = ContentScale.Crop,
            modifier = Modifier.fillMaxWidth())
        Box(modifier = Modifier
            .size(32.dp)
            .align(Alignment.TopEnd)) {
            Image(painter = painterResource(id = R.drawable.schedule),
                contentDescription = null,
                modifier = Modifier
                    .fillMaxSize()
                    .padding(top = 8.dp, end = 8.dp),
                contentScale = ContentScale.Fit)
        }
    }
    Card(modifier = Modifier
        .height(44.dp)
        .fillMaxWidth()) {
        Text(text = cardTitle,
            style = MaterialTheme.typography.h6,
            modifier = Modifier
                .padding(horizontal = 16.dp, vertical = 8.dp)
                .clip(RoundedCornerShape(bottomStart = 8.dp, bottomEnd = 8.dp)))
    }
}

Code Explanation:::

I'm getting a list of tools details which is having tool image, title, description from server.

imgURl -> url for image

cardTitle -> tool's name

Problem ::: Card is taking the whole width. Earlier, I used weight(1f) when the data was hardcoded and I don't have to retrieve it from backend. Also, I'm going to use it on the Homescreen, so the grid shouldn't be scrollable.

PLEASE VISIT THIS DRIVE LINK FOR MORE DETAILS, I have added code snippet and images + screen recording for better understanding


Solution

  • You can use official LazyVerticalGrid

    @Composable
    fun VerticalImageCards(toolsList: List<HealthTool>) {
        val domainName = stringResource(id = R.string.media_url) {
    
         LazyVerticalGrid(
                columns = GridCells.Fixed(2),
                modifier = modifier,
                state = rememberLazyGridState()
            ) {
           
             items(toolsList) { 
               val imgUrl = "$domainName${it.url}"
               ToolsCardLayout(cardTitle = it.title, imgUrl = imageUrl)
            }
        }
    }