androidanimationjitpacklazyvgridcompose

Animating items in a LazyVerticalGrid


I have a List<List<Thing>> and show each list in separate items in my lazyVerticalGrid as they have different layouts. The list can be filtered to less items and should be removed from the LazyVerticalGrid.

I have done two different implementations:

  1. With FilteredList iteration:

    LazyVerticalGrid(
                    modifier = modifier
                        .fillMaxSize(),
                    contentPadding = PaddingValues(horizontal = 16.dp),
                    columns = GridCells.Fixed(MAX_NUMBER_OF_COLUMNS),
                    verticalArrangement = Arrangement.spacedBy(16.dp),
                    horizontalArrangement = Arrangement.spacedBy(17.dp)
                ) { something ->
                    filteredList.forEach {   
                        when (something.section) {
                            Section.1,
                            Section.2 -> {
                                items(items = items,
                                    span = { GridItemSpan(MAX_NUMBER_OF_COLUMNS) },
                                    key = { it.id }) { item ->
                                    Something12Composable(
                                        item
                                    )
                                }
                            }
    
                            Section.3 -> {
                                items(items = items,
                                    span = { GridItemSpan(MAX_NUMBER_OF_COLUMNS) },
                                    key = { it.id }) { item ->
                                    Something3Composable(
                                        item
                                    )
                                }
                            }
                        }
                    }
                }
            }
    
    
    
  2. With AnimatedVisibility:

    LazyVerticalGrid(
                modifier = modifier
                    .fillMaxSize(),
                contentPadding = PaddingValues(horizontal = 16.dp),
                columns = GridCells.Fixed(MAX_NUMBER_OF_COLUMNS),
                verticalArrangement = Arrangement.spacedBy(16.dp),
                horizontalArrangement = Arrangement.spacedBy(17.dp)
            ) { something ->
                unfilteredList.forEach {
                    val isVisible: Boolean = // check if it should be visible 
                    when (something.section) {
                        Section.1,
                        Section.2 -> {
                            items(items = it.deeds,
                                span = { GridItemSpan(MAX_NUMBER_OF_COLUMNS) },
                                key = { it.id }) { item ->
                                AnimatedVisisbility(isVisbile){
                                    Something12Composable(
                                       item
                                    )
                                }
                            }
                        }
    
                        Section.3 -> {
                            items(items = it.deeds,
                                span = { GridItemSpan(MAX_NUMBER_OF_COLUMNS) },
                                key = { it.id }) { item ->
                                AnimatedVisisbility(isVisbile){
                                    Something3Composable(
                                        item
                                    )
                            }
                        }
                    }
                }
            }
        }
    
    

Both solutions work with some flaws. I want to have animation when items disappear or appear. The solution #1 has no animation and I haven't been able to add one. The solution #2 has animation but for some reason it adds empty space on top further down the list the items are in the unfilteredList which I can't remove it.

How can I have the animation for the appearing disappearing items without adding unnecessary space?


Solution

  • After reading a lot of answers and bug reports, I figured out my mistake. The compose already has the Modifier.animateItem extension function in LazyGridItemScope. My fault was that I didn't pass the Modifier from the LazyVerticalGrid to my Composables in all item/s members. It is limited animation and does not support Enter/ExitTransition but it does what I needed.

    items(items = items,
          span = { GridItemSpan(MAX_NUMBER_OF_COLUMNS) },
          key = { it.id }) { item ->
                                Something12Composable(Modifier
                                   .animateItem(...), // This Modifier is in the LazyGrideItemScop and passing/using it in the composable add the animation.
                                    item
                                )
                            }