0Pricing
Android Academy · Aula

Paginação em listas do Compose

Renderize dados paginados com LazyColumn.

Paginação em listas do Compose é uma aula grátis de Android Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Android Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Android Academy inclui 4 aulas no total.

Renderizando dados paginados no Compose

A camada de dados fornece um Flow<PagingData<Article>>. A biblioteca paging-compose transforma esse fluxo em algo que uma LazyColumn pode renderizar, incluindo o carregamento sob demanda conforme o usuário rola.

A principal ponte é collectAsLazyPagingItems().

collectAsLazyPagingItems

Chame collectAsLazyPagingItems() no fluxo dentro de um componente. Ele retorna um objeto LazyPagingItems que acompanha os itens carregados e os estados de carregamento, recompondo a interface conforme as páginas chegam.

import androidx.paging.compose.collectAsLazyPagingItems

@Composable
fun ArticleScreen(viewModel: ArticleViewModel) {
    val articles = viewModel.articles.collectAsLazyPagingItems()
    ArticleList(articles)
}

items() com LazyPagingItems

Dentro de uma LazyColumn, use a sobrecarga de items() da paginação. Ela lê de LazyPagingItems e dispara o carregamento da próxima página quando o usuário se aproxima do fim.

Cada item pode ser null quando os espaços reservados estão ativados; portanto, trate esse caso.

import androidx.compose.foundation.lazy.LazyColumn
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.items

@Composable
fun ArticleList(articles: LazyPagingItems<Article>) {
    LazyColumn {
        items(articles) { article ->
            if (article != null) {
                ArticleRow(article)
            }
        }
    }
}

Chaves estáveis para os itens

Forneça a cada linha uma chave estável para que o Compose acompanhe os itens com eficiência durante o carregamento das páginas e evite recomposições desnecessárias.

Use o auxiliar itemKey da paginação com uma propriedade única e estável, como o identificador do item.

import androidx.paging.compose.itemKey

LazyColumn {
    items(
        count = articles.itemCount,
        key = articles.itemKey { it.id }
    ) { index ->
        val article = articles[index]
        if (article != null) ArticleRow(article)
    }
}

Lendo os estados de carregamento

LazyPagingItems.loadState expõe o estado atual de carregamento e erro para três operações:

  • refresh - o carregamento inicial ou por gesto de puxar para atualizar
  • append - carregamento da próxima página (rolagem para baixo)
  • prepend - carregamento da página anterior (rolagem para cima)
import androidx.paging.LoadState

val refresh = articles.loadState.refresh
val append = articles.loadState.append

val isInitialLoading = refresh is LoadState.Loading
val isLoadingMore = append is LoadState.Loading

Estados de carregamento e vazio em tela cheia

Use o estado refresh para controlar a primeira impressão: um indicador centralizado durante o carregamento, uma tela de erro em caso de falha ou uma mensagem vazia quando não houver nada para exibir.

when (val refresh = articles.loadState.refresh) {
    is LoadState.Loading -> FullScreenSpinner()
    is LoadState.Error -> FullScreenError(
        message = refresh.error.message,
        onRetry = { articles.retry() }
    )
    is LoadState.NotLoading -> {
        if (articles.itemCount == 0) EmptyState()
        else ArticleList(articles)
    }
}

Indicador no rodapé durante o acréscimo

Para exibir um pequeno indicador na parte inferior enquanto a próxima página é carregada, adicione um item extra à LazyColumn com base no estado de carregamento append.

LazyColumn {
    items(count = articles.itemCount, key = articles.itemKey { it.id }) { index ->
        articles[index]?.let { ArticleRow(it) }
    }

    if (articles.loadState.append is LoadState.Loading) {
        item {
            Box(Modifier.fillMaxWidth().padding(16.dp), Alignment.Center) {
                CircularProgressIndicator()
            }
        }
    }
}

Nova tentativa em caso de erro

Quando um acréscimo falhar, exiba uma linha de nova tentativa na parte inferior. Chamar articles.retry() tenta novamente apenas o carregamento que falhou — não recarrega a lista inteira.

val append = articles.loadState.append
if (append is LoadState.Error) {
    item {
        Row(Modifier.fillMaxWidth().padding(16.dp), Arrangement.Center) {
            Text("Couldn't load more")
            Spacer(Modifier.width(8.dp))
            Button(onClick = { articles.retry() }) { Text("Retry") }
        }
    }
}

Puxar para atualizar

Dispare um novo carregamento com articles.refresh(). Combine isso com o recurso de puxar para atualizar do Material 3, controlando o indicador a partir do estado de carregamento refresh.

import androidx.compose.material3.pulltorefresh.PullToRefreshBox

val isRefreshing = articles.loadState.refresh is LoadState.Loading
PullToRefreshBox(
    isRefreshing = isRefreshing,
    onRefresh = { articles.refresh() }
) {
    ArticleList(articles)
}

Cabeçalho e separadores

Você pode misturar livremente itens paginados com conteúdo não paginado na mesma LazyColumn. Adicione um cabeçalho fixo, uma barra de pesquisa ou separadores de seção ao redor da chamada paginada de items().

Como tudo fica em uma única LazyColumn, a rolagem permanece unificada e suave.

LazyColumn {
    item { SearchBar(query, onQueryChange) }

    items(count = articles.itemCount, key = articles.itemKey { it.id }) { index ->
        val article = articles[index]
        if (article != null) {
            ArticleRow(article)
            HorizontalDivider()
        }
    }

    if (articles.loadState.append.endOfPaginationReached) {
        item { Text("You're all caught up", Modifier.padding(16.dp)) }
    }
}

Visualizando listas paginadas

Para visualizações do Compose e testes, você não precisa de uma rede real. Envolva dados de exemplo em PagingData.from(...) e exponha-os como um fluxo.

Isso permite criar e visualizar a interface da lista de forma isolada.

import androidx.paging.PagingData
import kotlinx.coroutines.flow.flowOf

@Preview
@Composable
fun ArticleListPreview() {
    val sample = listOf(Article(1, "Hello"), Article(2, "World"))
    val flow = flowOf(PagingData.from(sample))
    ArticleList(flow.collectAsLazyPagingItems())
}

Verificação rápida

Qual função converte um Flow<PagingData> em algo que uma LazyColumn do Compose pode renderizar?

Recapitulação: paginação no Compose

Você renderizou dados paginados no Jetpack Compose:

  • collectAsLazyPagingItems() conecta o fluxo à interface
  • A sobrecarga de items() da paginação carrega mais dados conforme você rola; trate os espaços reservados null
  • Use itemKey { it.id } para obter chaves estáveis
  • loadState.refresh/append/prepend controla indicadores, erros e estados vazios
  • retry() e refresh() recuperam-se de falhas e recarregam os dados

Próximo: combinar rede e banco de dados com RemoteMediator.

Perguntas Frequentes

A aula “Paginação em listas do Compose” é grátis?

Sim — o texto completo de “Paginação em listas do Compose” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Android Academy, atualize para CoddyKit PRO. O curso de Android Academy inclui 4 aulas no total.

O que vou aprender em “Paginação em listas do Compose”?

Renderize dados paginados com LazyColumn. Você pratica Android Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Android Academy?

Nenhuma experiência prévia é necessária. Android Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Paginação em listas do Compose”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Android Academy?

Sim. Cada aula de Android Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que usar paginação
  2. PagingSource e Pager
  3. Paginação em listas do Compose
  4. RemoteMediator e cache
← Voltar para Android Academy