Listas lentas em uma grade

Ícone de avaliação de quatro estrelas

O elemento combinável Grid cria layouts de tela estruturais e bidimensionais. Grid define uma estrutura de layout responsiva usando faixas (linhas e colunas) e lacunas explicitamente definidas como a arquitetura básica da interface.

Como o Grid é um contêiner estrutural, e não de carregamento lento, é necessário definir explicitamente cada elemento colocado nele sem reciclar itens ao rolar a tela. Como resultado, renderizar conjuntos de dados grandes ou dinâmicos diretamente em um Grid pode causar gargalos de desempenho, já que todos os itens são compostos simultaneamente.

Para mostrar grandes coleções de dados em um layout de tela estruturado, incorpore componentes lentos, como LazyColumn ou LazyRow, nas células Grid. Mas atenção: as faixas flexíveis (com especificações como 1.fr) consultam os tamanhos intrínsecos dos elementos filhos. Como o SubcomposeLayout não oferece suporte a transmissões de medição intrínseca, colocar uma lista lenta dentro de uma faixa flexível causa uma falha de IllegalStateException. Para colocar listas lentas com segurança em uma faixa de grade flexível, use o dimensionamento GridTrackSize.MinMax (como minmax(0.dp, 1.fr)) para ignorar a medição intrínseca.

Layout de tela com um cabeçalho na parte de cima, uma lista rolável de itens na área de conteúdo principal e um rodapé na parte de baixo.
Figura 1. Layout de tela estrutural com um cabeçalho, um rodapé e um LazyColumn incorporado para o conteúdo.

Práticas recomendadas

  • Use listas lentas em vez de loops explícitos grandes: para mostrar conjuntos de dados grandes ou dinâmicos em um Grid estruturado, incorpore componentes lentos (normalmente LazyColumn ou LazyRow) em células de grade específicas, em vez de criar loops explícitos grandes em itens, já que o Grid não recicla itens e tem um limite de 1.000 faixas.
  • Use o dimensionamento de faixa MinMax para listas lentas: como LazyColumn e LazyRow não oferecem suporte a passagens de medição intrínseca (consulte SubcomposeLayout), use GridTrackSize.MinMax em faixas flexíveis que hospedam componentes lentos para ignorar medições intrínsecas com segurança.

Ingredientes

  • Grid: layout combinável que coloca itens em uma estrutura de grade bidimensional configurada usando faixas explícitas de linhas e colunas.
  • LazyColumn: lista de rolagem vertical que compõe e recicla apenas os itens visíveis na tela.
  • GridTrackSize.MinMax: propriedade de dimensionamento de faixa que define limites flexíveis (min e max) para hospedar componentes lentos com segurança sem acionar falhas de medição de ambiente de execução.
  • gridItem: extensão do Compose Modifier que atribui um elemento da interface a uma célula específica ou área nomeada dentro de um Grid.

Etapas

Estruture o layout da tela definindo identificadores de área semântica, configurando faixas de grade com dimensionamento minmax para compatibilidade com listas lentas e incorporando LazyColumn dentro da área de conteúdo da grade.

1. Configurar faixas de grade e áreas nomeadas

Crie uma classe enum para representar as diferentes regiões do layout da tela e defina uma lambda GridConfigurationScope para as faixas de layout e as áreas nomeadas. Use GridTrackSize.MaxContent para que as linhas de cabeçalho e rodapé se ajustem às dimensões do conteúdo e use minmax(0.dp, 1.fr) para que a faixa de conteúdo que hospeda a lista lenta aloque espaço flexível sem consultar medições intrínsecas não compatíveis:

enum class ScreenArea {
    Header,
    Content,
    Footer
}


val lazyConfig: GridConfigurationScope.() -> Unit = {
    column(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)
    row(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)

    area(ScreenArea.Header, row = 1, column = 1)
    area(ScreenArea.Content, row = 2, column = 1)
    area(ScreenArea.Footer, row = 3, column = 1)
    gap(8.dp)
}

2. Colocar componentes estáticos na grade

No elemento combinável, transmita lazyConfig para o contêiner Grid. Dentro da lambda content, coloque componentes estáticos (Header e Footer) e posicione-os usando Modifier.gridItem() com os respectivos identificadores de área.

3. Incorporar LazyColumn na área de conteúdo

Na célula de conteúdo, incorpore LazyColumn usando Modifier.gridItem(ScreenArea.Content). Como a faixa de conteúdo foi configurada com minmax(0.dp, 1.fr) na Etapa 1, o LazyColumn pode medir e reciclar itens com segurança ao rolar a tela sem consultar dimensões intrínsecas não compatíveis:

@Composable
fun GridWithLazyColumn(
    modifier: Modifier = Modifier,
    items: List<String> = emptyList(),
) {
    Grid(
        modifier = modifier.fillMaxSize(),
        config = lazyConfig
    ) {
        Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp))
        Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp))

        // LazyColumn placed in the content area for large datasets
        LazyColumn(
            modifier = Modifier
                .gridItem(ScreenArea.Content)
                .fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { item ->
                Text(item, Modifier.padding(16.dp))
            }
        }
    }
}

Resultados

O layout da tela agora usa a API Grid para definir a estrutura geral bidimensional da página, incorporando um LazyColumn em uma faixa flexível com dimensionamento minmax para reciclar itens de lista de forma eficiente e evitar exceções de execução.

Outros recursos