Items in Compose StaggeredGrid rearranging themselves when scrolling up

87 views Asked by At

I have implemented a LazyVerticalStaggeredGrid which shows GIFs. The GIFs are displayed using the AsyncImage from Coil using a url from Giphy. The items asynchronously load into the grid without issue. Scrolling down works as expected, however, scrolling up makes the items rearrange themselves. Here is my implementation of the grid:

@Composable
fun GifGrid(
    modifier: Modifier = Modifier,
    gifList: List<GiphyItem>
) {
    LazyVerticalStaggeredGrid(
        columns = StaggeredGridCells.Fixed(3),
        modifier = modifier,
        verticalItemSpacing = 12.dp,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        contentPadding = PaddingValues(vertical = 8.dp),
        content = {
            items(gifList, key = { it.id }) { item ->
                AsyncImage(
                    model = ImageRequest.Builder(LocalContext.current)
                        .data(item.images.downsized.url)
                        .decoderFactory(ImageDecoderDecoder.Factory())
                        .build(),
                    contentDescription = null,
                    modifier = Modifier
                        .clip(RoundedCornerShape(6.dp)),
                    contentScale = ContentScale.Crop
                )
            }
        }
    )
}

Here is a video of the bug

I have tried a few things to diagnose the issue:

  • Tried observing gifList with LaunchedEffect. There were no recompositions happening.
  • Tried various different sizes of GIFs. That did not have an effect.
  • Tried replicating the bug with images from drawables and url. Could not replicate bug.
  • Tried other grid views. Got the same behavior.

I also saw some implementations for fixing a bug like this in XML but I am not sure how to transfer that to Compose.

2

There are 2 answers

1
Daniele Segato On BEST ANSWER

I think your issue is that you didn't give a size to the images so it only becomes available when loaded. Scrolling down this isn't an issue but scrolling up it becomes one because content below it moves...

Set a size to the items and the issue should go away

1
uragiristereo On

If your API gives you width and height parameter, you can allocate the composable size first before Coil is loaded by setting a Modifier.aspectRatio(width / height).