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

1

9

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?

Bayadere answered 26/5, 2021 at 9:58 Comment(0)
B
10
@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
        }
    }
}
Bayadere answered 27/5, 2021 at 10:0 Comment(3)
getAsState is deprecated in alpha14, now you can directly use the index as lazyMovieItems[index].Rena
Be careful using this solution: the for loop will every single time the user will fetch new items and, if you have a lot of results (e.g. hundreds of thousands or millions), it will easily run out of memory or degrade the scroll performance (think about iterating over a million items on the UI thread every time you fetch a new page).Cayser
is not using lazyMovieItems.itemSnapshotList gives better performance then loop for all elements (lazyMovieItems.itemCount)?Mightily

© 2022 - 2024 — McMap. All rights reserved.