LazyRow — é uma função compostável no Jetpack Compose para criar listas horizontais com carregamento lento de elementos. Ao contrário do Row, o LazyRow cria apenas os elementos visíveis e os reutiliza durante a rolagem horizontal. De acordo com Google Android Documentation, 2025, o LazyRow é o equivalente horizontal do LazyColumn e é eficaz para carrosséis, galerias e menus horizontais em aplicações móveis.
Principais pontos
LazyRow — é uma função compostável que implementa uma lista horizontal rolável com carregamento lento de elementos. Ao contrário do Row, que renderiza todos os elementos filhos simultaneamente, o LazyRow cria apenas os elementos visíveis na área de visualização.
O LazyRow funciona com o mesmo princípio do LazyColumn, mas organiza os elementos horizontalmente. Ao rolar para a esquerda ou direita, os elementos que saem da área de visualização são reutilizados para exibir novos. Isso é criticamente importante para galerias com muitas imagens ou listas longas de categorias.
De acordo com Android Developers Blog, 2024, o LazyRow usa a mesma arquitetura LazyList do LazyColumn, incluindo LazyListState, mecanismo de reutilização via Pool e suporte para diferentes tipos de elementos. A eficiência máxima é alcançada com altura fixa dos elementos.
LazyRow aceita os parâmetros modifier, state, contentPadding, reverseLayout, horizontalArrangement e verticalAlignment. O conteúdo é definido através das funções DSL items e item, similar ao LazyColumn.
@Composable
fun SimpleLazyRow() {
val items = (1..50).toList()
LazyRow(
modifier = Modifier.fillMaxWidth().height(100.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(start = 16.dp, end = 16.dp)
) {
items(items) { item ->
Box(
modifier = Modifier.size(80.dp).background(Color.Gray)
) {
Text(text = "$item", modifier = Modifier.align(Alignment.Center))
}
}
}
}
horizontalArrangement gerencia a distribuição dos elementos ao longo do eixo horizontal dentro do LazyRow. Os mesmos valores de Arrangement do Row estão disponíveis: Start, Center, End, SpaceBetween, SpaceEvenly, SpaceAround e spacedBy com espaçamento personalizado.
contentPadding adiciona preenchimento nas bordas do contêiner LazyRow. Ao contrário do Modifier.padding, o contentPadding é levado em consideração durante a rolagem: o primeiro elemento terá preenchimento da borda esquerda, o último da borda direita. De acordo com Material Design Guidelines, 2025, o contentPadding é obrigatório para carrosséis e galerias para que o primeiro e o último elemento não grudem na borda da tela.
verticalAlignment alinha os elementos verticalmente dentro do LazyRow. Por padrão, Alignment.Top é usado. Para centralizar elementos de diferentes alturas, use Alignment.CenterVertically, o que é útil para carrosséis com imagens de diferentes proporções.
| Parâmetro | Descrição | Valor padrão |
|---|---|---|
| horizontalArrangement | Distribuição horizontal dos elementos | Arrangement.Start |
| contentPadding | Preenchimento nas bordas do contêiner | PaddingValues(0.dp) |
| verticalAlignment | Alinhamento vertical | Alignment.Top |
| reverseLayout | Ordem inversa dos elementos | false |
| userScrollEnabled | Habilitar rolagem do usuário | true |
LazyListState para LazyRow funciona de forma idêntica ao LazyColumn: ele rastreia o primeiro elemento visível, deslocamento e posição geral de rolagem. O estado é criado através de rememberLazyListState() e passado para o parâmetro state.
O controle programático de rolagem do LazyRow é feito com os mesmos métodos: animateScrollToItem para animação suave e scrollToItem para rolagem instantânea. Ambos são chamados dentro de uma corrotina. Isso é útil para carrosséis com botões de avanço/recuo ou para rolagem automática.
De acordo com Android Developers, 2024, o LazyRow também suporta SnapFlingBehavior — comportamento para rolagem rápida que para no elemento mais próximo em vez de entre elementos. Isso cria um efeito de ajuste familiar para carrosséis e galerias.
@Composable
fun CarouselWithSnap() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
val items = listOf("A", "B", "C", "D", "E")
Column {
LazyRow(
state = listState,
flingBehavior = SnapFlingBehavior(listState),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items) { item ->
Card(modifier = Modifier.width(150.dp)) {
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Button(onClick = {
scope.launch {
listState.animateScrollToItem(0)
}
}) { Text("Para começar") }
}
}
}
O primeiro exemplo — LazyRow para uma galeria de imagens com pré-visualizações. Cada elemento é um Box com uma imagem e uma legenda. O LazyRow lida eficientemente com dezenas e centenas de imagens, carregando apenas as visíveis.
@Composable
fun ImageGallery(images: List<String>) {
LazyRow(
contentPadding = PaddingValues(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(images, key = { it }) { url ->
AsyncImage(
model = url,
contentDescription = "Image",
modifier = Modifier.size(120.dp)
)
}
}
}
O segundo exemplo — LazyRow para uma lista de categorias com ícones. As categorias são exibidas como chips e o usuário pode rolá-las horizontalmente. O LazyRow com spacedBy e contentPadding cria espaçamento entre categorias e nas bordas.
@Composable
fun CategoryChips(categories: List<String>) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(categories, key = { it }) { category ->
AssistChip(
onClick = {},
label = { Text(category) }
)
}
}
}
A escolha entre LazyRow e Row depende do número de elementos. Row é adequado para 5–10 elementos que estão sempre visíveis na tela. LazyRow é essencial quando há muitos elementos ou sua quantidade é dinâmica.
Row renderiza todos os elementos de uma vez, causando atrasos com um grande número de elementos. LazyRow renderiza apenas os visíveis, tornando-o preferível para listas roláveis. De acordo com Android Developers Blog, 2024, o limiar é de aproximadamente 10 elementos: se houver mais elementos, use LazyRow.
LazyRow também suporta animações, SnapFlingBehavior e agrupamento através de separadores, tornando-o mais flexível para interfaces complexas. Row é mais simples e não requer LazyListState, mas não é otimizado para listas longas.
Perguntas frequentes
LazyRow rola horizontalmente e organiza os elementos da esquerda para a direita, enquanto o LazyColumn rola verticalmente de cima para baixo. Ambos usam os mesmos princípios de carregamento lento, LazyListState e funções DSL items.
Passe SnapFlingBehavior(listState) para o parâmetro flingBehavior do LazyRow. O SnapFlingBehavior força o LazyRow a parar no elemento mais próximo em vez de entre elementos, criando um efeito de ajuste para carrosséis.
Rastreie o último elemento visível através de LazyListState.layoutInfo e carregue novos dados quando o último elemento se aproximar do final da lista. Para rolagem circular, use uma implementação personalizada com duplicação de elementos.
Sim, LazyRow pode ser aninhado dentro de LazyColumn. Este é um padrão padrão para criar páginas complexas com carrosséis horizontais dentro de uma lista vertical. Cada LazyRow deve ter uma altura fixa para funcionamento correto.
Use LazyListState.layoutInfo.visibleItemsInfo e compare o índice do último elemento visível com o total menos um. Quando esses valores coincidem, o LazyRow está no final da lista.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também