Search code examples
androidkotlinandroid-jetpackandroid-jetpack-composeandroid-paging

How to use LazyColumn stickyHeader in combination with Paging in Android Jetpack Compose?


I have implemented LazyColumn with Paging, but I'm now trying to add sticky headers as well.

The stickyHeader() function is not available inside the items() scope, so I don't see how this should work.

@Composable
fun MovieList(movies: Flow<PagingData<Movie>>) {
    val lazyMovieItems: LazyPagingItems<Movie> = movies.collectAsLazyPagingItems()

    LazyColumn {
        // TODO: Add sticky headers
        items(lazyMovieItems) { movie ->
            MovieItem(movie = movie!!)
        }
    }
}

How can I add the stickyHeaders?


Solution

  • @Composable
    fun MovieList(movies: Flow<PagingData<Movie>>) {
        val lazyMovieItems = movies.collectAsLazyPagingItems()
    
        LazyColumn {
            val itemCount = lazyMovieItems.itemCount
            var lastCharacter: Char? = null
    
            for (index in 0 until itemCount) {
                // Gets item without notifying Paging of the item access,
                // which would otherwise trigger page loads
                val movie = lazyMovieItems.peek(index)
                val character = movie?.name?.first()
    
                if (movie !== null && character != lastCharacter) {
                    stickyHeader(key = character) {
                        MovieHeader(character)
                    }
                }
    
                item(key = movie?.id) {
                    // Gets item, triggering page loads if needed
                    val movieItem = lazyMovieItems[index]
    
                    Movie(movieItem)
                }
    
                lastCharacter = character
            }
        }
    }