Desglose del modificador por fase

Jetpack Compose ejecuta modificadores en distintas fases. En el siguiente desglose, se muestra a qué fase pertenecen los modificadores comunes y cuándo se evalúan sus argumentos o lambdas.

Fase 1: Fase de composición

Estos modificadores evalúan los argumentos de forma síncrona dentro del @Composable cuerpo. Cualquier estado que se lea aquí registra una dependencia con el alcance de reinicio de Composable y activa una recomposición completa cuando cambia.

  • Modificadores de tamaño y dimensión estáticos:
    • Modifier.size(dp), Modifier.width(dp), Modifier.height(dp)
    • Modifier.fillMaxSize(), Modifier.fillMaxWidth(), Modifier.fillMaxHeight()
    • Modifier.wrapContentSize(), Modifier.wrapContentWidth(), Modifier.wrapContentHeight()
    • Modifier.requiredSize(), Modifier.defaultMinSize()
    • Modifier.aspectRatio(ratio)
    • Modifier.weight(weight) (en RowScope o ColumnScope)
    • Modifier.width(IntrinsicSize.Min / Max)
    • Modifier.height(IntrinsicSize.Min / Max)
  • Espaciado y ajustes estáticos:
    • Modifier.padding(all = dp), Modifier.padding(start, top, end, bottom)
    • Modifier.windowInsetsPadding(insets), Modifier.statusBarsPadding()
  • Modificadores visuales de valor directo:
    • Modifier.alpha(float) (lee el estado durante la composición)
    • Modifier.rotate(degrees) (lee el estado durante la composición)
    • Modifier.scale(scaleX, scaleY) (lee el estado durante la composición)
    • Modifier.background(color = Color, shape = Shape)
    • Modifier.border(width, color, shape)
    • Modifier.shadow(elevation, shape)
    • Modifier.clip(shape)
    • Modifier.blur(radius)
  • Modificadores de posición estáticos:
    • Modifier.offset(x = dp, y = dp) (sobrecarga de valor directo)
    • Modifier.absoluteOffset(x = dp, y = dp)
  • Modificadores dinámicos componibles:
    • Modifier.composed { ... } (ejecuta el cuerpo de la fábrica durante la composición)

Fase 2: Fase de diseño

La fase de diseño se divide en dos subpasos distintos con diferentes alcances de invalidación:

Paso 2A: Medición

Determina el tamaño (width, height) y las restricciones. La lectura de estado aquí activa la nueva medición y la reubicación:

  • Modifier.layout { measurable, constraints -> ... }: Código anterior a la ejecución de layout(w, h) durante la medición.

Paso 2B: Devoluciones de llamada de posición y diseño

Determina la posición de la coordenada (x, y). El estado que se lee aquí solo activa la reubicación (se omiten la medición y la composición):

  • Modifier.offset { IntOffset(x, y) } (sobrecarga de lambda)
  • Modifier.absoluteOffset { IntOffset(x, y) } (sobrecarga de lambda)
  • Modifier.layout { ... layout(w, h) { placeable.place(x, y) } }: Código dentro del bloque layout(w, h) { ... }.
  • Modifier.onPlaced { layoutCoordinates -> ... }: Se invoca después de que se determinan las coordenadas principales durante la colocación.
  • Modifier.onSizeChanged { intSize -> ... }: Se invoca después de que se completa la medición del diseño si cambió el tamaño.
  • Modifier.onGloballyPositioned { layoutCoordinates -> ... }: Se invoca después de que finaliza todo el pase de diseño de la ventana.

Fase 3: Fase de dibujo

Estos modificadores se ejecutan durante el dibujo del lienzo. La lectura de estado dentro de estos bloques omite tanto la composición como el diseño y solo ejecuta el paso de dibujo:

  • Modifier.graphicsLayer { ... }:
    • Propiedades actualizadas en la función lambda: alpha, translationX, translationY, scaleX, scaleY, rotationX, rotationY, rotationZ, shadowElevation, shape, clip, renderEffect, transformOrigin.
  • Modifier.drawBehind { ... }:
    • Dibuja comandos de lienzo detrás del contenido componible.
  • Modifier.drawWithContent { ... }:
    • Controla el orden de dibujo con drawContent().
  • Modifier.drawWithCache { ... }:
    • El bloque externo se ejecuta en los cambios de tamaño o diseño para almacenar en caché los objetos Path, Paint o Brush; onDrawBehind o onDrawWithContent se ejecuta en cada dibujo de fotograma.

Fuera del bucle de recomposición: modificadores de observación

Algunos modificadores operan fuera de las tres fases de fotogramas para controlar la accesibilidad, la entrada del usuario y las observaciones del ciclo de vida.

Semántica y accesibilidad

Procesa propiedades semánticas para servicios de accesibilidad (TalkBack) y pruebas:

  • Modifier.semantics { ... }
  • Modifier.clearAndSetSemantics { ... }

Entrada, gestos y eventos

Funciona fuera de la canalización de renderización de fotogramas de tres fases, ya que recibe eventos de movimiento del SO y las interacciones del usuario:

  • Modifier.pointerInput(key) { detectTapGestures { ... } } / detectDragGestures / awaitPointerEventScope
  • Modifier.clickable(enabled, onClickLabel) { ... }
  • Modifier.combinedClickable { ... }
  • Modifier.toggleable { ... }
  • Modifier.selectable { ... }
  • Modifier.draggable(...) / Modifier.scrollable(...) / Modifier.draggable2D(...)
  • Modifier.onFocusChanged { focusState -> ... }
  • Modifier.onKeyEvent { keyEvent -> ... }
  • Modifier.onVisibilityChanged { isVisible -> ... }: Se invoca la devolución de llamada cuando cambia la visibilidad de un elemento componible después del retraso configurado, en una corrutina.

Referencia rápida: Fase de valor versus fase de lambda

Leer un valor de estado en una lambda difiere la lectura a una fase posterior, lo que omite las fases anteriores cuando cambia ese estado:

Modificador / patrón Valor directo (composición) Lambda Variant (fase aplazada) Cuándo cambian los estados
Desplazamiento Modifier.offset(x, y) Modifier.offset { IntOffset(x, y) } Diseño (posición) (omite la composición)
Alfa / Opacidad Modifier.alpha(alpha) Modifier.graphicsLayer { this.alpha = alpha } Dibujo (se omite Composición y diseño)
Rotación Modifier.rotate(degrees) Modifier.graphicsLayer { rotationZ = degrees } Dibujo (se omite Composición y diseño)
Escala Modifier.scale(scale) Modifier.graphicsLayer { scaleX = s; scaleY = s } Dibujo (se omite Composición y diseño)
Traducción Modifier.padding(...) Modifier.graphicsLayer { translationX = ... } Dibujo (se omite Composición y diseño)
Color de fondo Modifier.background(color) Modifier.drawBehind { drawRect(color) } Dibujo (se omite Composición y diseño)
Desplazamiento / Paralaje Modifier.offset(scroll.dp) Modifier.offset { IntOffset(0, scroll) } Diseño (posición) (omite la composición)

Asignación de la interfaz Modifier.Node

En el caso de los modificadores personalizados que usan la API de Modifier.Node de alto rendimiento, las fases se asignan directamente a las interfaces de capacidad de los nodos:

Fase Interfaz de Modifier.Node Métodos principales
Diseño (Medir y colocar) LayoutModifierNode measure(measurable, constraints)
Diseño (coordenadas globales) GlobalPositionAwareModifierNode onGloballyPositioned(coordinates)
Diseño (posición) LayoutAwareModifierNode onRemeasured(size), onPlaced(coordinates)
Dibujo DrawModifierNode draw(ContentDrawScope)
Entrada / Puntero PointerInputModifierNode onPointerEvent(...), onCancelPointerInput()
Semántica SemanticsModifierNode applySemantics(SemanticsPropertyReceiver)
Enfoque FocusEventModifierNode onFocusEvent(focusState)