Listas diferidas en una cuadrícula

Ícono de calificación de cuatro estrellas

El elemento Grid componible crea diseños de pantalla estructurales bidimensionales. Grid define una estructura de diseño responsivo con pistas (filas y columnas) y espacios explícitamente definidos como la arquitectura fundamental de tu IU.

Dado que Grid es un contenedor estructural en lugar de uno de carga diferida, debes definir de forma explícita cada elemento que se coloque dentro de él sin reciclar elementos cuando se desplaza. Como resultado, renderizar conjuntos de datos grandes o dinámicos directamente dentro de un Grid puede causar cuellos de botella en el rendimiento, ya que todos los elementos se componen de forma simultánea.

Para mostrar grandes colecciones de datos en un diseño de pantalla estructurado, incorpora componentes de carga diferida, como LazyColumn o LazyRow, en tus celdas Grid. Sin embargo, ten en cuenta que los segmentos flexibles (con especificaciones como 1.fr) consultan los tamaños intrínsecos de los elementos secundarios. Dado que SubcomposeLayout no admite pases de medición intrínsecos, colocar una lista diferida dentro de un segmento flexible provoca una falla de IllegalStateException. Para colocar de forma segura listas diferidas dentro de un carril de cuadrícula flexible, debes usar el tamaño GridTrackSize.MinMax (como minmax(0.dp, 1.fr)) para omitir el paso de medición intrínseca.

Diseño de pantalla con un encabezado en la parte superior, una lista desplazable de elementos en el área de contenido principal y un pie de página en la parte inferior.
Figura 1: Diseño de pantalla estructural con un encabezado, un pie de página y un LazyColumn integrado para el contenido.

Prácticas recomendadas

  • Usa listas diferidas en lugar de bucles explícitos grandes: Para mostrar conjuntos de datos grandes o dinámicos dentro de un Grid estructurado, incorpora componentes diferidos (por lo general, LazyColumn o LazyRow) dentro de celdas de cuadrícula específicas en lugar de crear bucles explícitos grandes sobre los elementos, ya que Grid no recicla elementos y tiene un límite de 1,000 pistas.
  • Usa el ajuste de tamaño de la pista MinMax para las listas diferidas: Dado que LazyColumn y LazyRow no admiten pases de medición intrínseca (consulta SubcomposeLayout), usa GridTrackSize.MinMax en pistas flexibles que alojan componentes diferidos para omitir las mediciones intrínsecas de forma segura.

Ingredientes

  • Grid: Diseño componible que coloca elementos en una estructura de cuadrícula bidimensional configurada con pistas de filas y columnas explícitas.
  • LazyColumn: Lista de desplazamiento vertical que solo compone y recicla los elementos que se ven en la pantalla.
  • GridTrackSize.MinMax: Es una propiedad de tamaño de pista que define límites flexibles (min y max) para alojar de forma segura componentes de carga diferida sin activar fallas de medición en el tiempo de ejecución.
  • gridItem: Extensión de Compose Modifier que asigna un elemento de la IU secundario a una celda específica o a un área con nombre dentro de un Grid.

Pasos

Estructura el diseño de la pantalla definiendo identificadores de área semántica, configurando pistas de cuadrícula con un tamaño de minmax para la compatibilidad con listas diferidas y, luego, incorpora LazyColumn dentro del área de contenido de la cuadrícula.

1. Configura pistas de cuadrícula y áreas con nombre

Crea una clase enum para representar las distintas regiones del diseño de la pantalla y define una expresión lambda GridConfigurationScope para los segmentos y las áreas con nombre del diseño. Usa GridTrackSize.MaxContent para las filas de encabezado y pie de página para que se ajusten a las dimensiones de su contenido, y usa minmax(0.dp, 1.fr) para el segmento de contenido que aloja la lista diferida para asignar espacio flexible sin consultar mediciones intrínsecas no admitidas:

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. Coloca componentes estáticos en la cuadrícula

En tu elemento componible, pasa lazyConfig al contenedor Grid. Dentro de la expresión lambda content, coloca componentes estáticos (Header y Footer) y posiciónalos con Modifier.gridItem() con sus respectivos identificadores de área.

3. Incorpora LazyColumn en el área de contenido

En la celda de contenido, incorpora LazyColumn con Modifier.gridItem(ScreenArea.Content). Dado que el segmento de contenido se configuró con minmax(0.dp, 1.fr) en el paso 1, LazyColumn puede medir y reciclar elementos de forma segura durante el desplazamiento sin consultar dimensiones intrínsecas no admitidas:

@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

El diseño de la pantalla ahora utiliza la API de Grid para definir la estructura general bidimensional de la página, mientras que incorpora un LazyColumn en un segmento flexible con un tamaño de minmax para reciclar elementos de la lista de manera eficiente y evitar excepciones en el tiempo de ejecución.

Recursos adicionales