Ripartizione dei modificatori per fase

Jetpack Compose esegue i modificatori in fasi distinte. La seguente suddivisione mostra a quale fase appartengono i modificatori comuni e quando vengono valutati i relativi argomenti o le relative espressioni lambda.

Fase 1: fase di composizione

Questi modificatori valutano gli argomenti in modo sincrono all'interno del @Composable corpo. Qualsiasi stato letto qui registra una dipendenza con l'ambito di riavvio di Composable e attiva una ricomposizione completa quando viene modificato.

  • Modificatori statici di dimensioni e ridimensionamento:
    • Modifier.size(dp), Modifier.width(dp) e Modifier.height(dp)
    • Modifier.fillMaxSize(), Modifier.fillMaxWidth() e Modifier.fillMaxHeight()
    • Modifier.wrapContentSize(), Modifier.wrapContentWidth() e Modifier.wrapContentHeight()
    • Modifier.requiredSize(), Modifier.defaultMinSize()
    • Modifier.aspectRatio(ratio)
    • Modifier.weight(weight) (in RowScope o ColumnScope)
    • Modifier.width(IntrinsicSize.Min / Max)
    • Modifier.height(IntrinsicSize.Min / Max)
  • Spaziatura e rientri statici:
    • Modifier.padding(all = dp), Modifier.padding(start, top, end, bottom)
    • Modifier.windowInsetsPadding(insets), Modifier.statusBarsPadding()
  • Modificatori visivi del valore diretto:
    • Modifier.alpha(float) (legge lo stato durante la composizione)
    • Modifier.rotate(degrees) (legge lo stato durante la composizione)
    • Modifier.scale(scaleX, scaleY) (legge lo stato durante la composizione)
    • Modifier.background(color = Color, shape = Shape)
    • Modifier.border(width, color, shape)
    • Modifier.shadow(elevation, shape)
    • Modifier.clip(shape)
    • Modifier.blur(radius)
  • Modificatori di posizione statici:
    • Modifier.offset(x = dp, y = dp) (valore diretto sovraccarico)
    • Modifier.absoluteOffset(x = dp, y = dp)
  • Modificatori componibili dinamici:
    • Modifier.composed { ... } (esegue il corpo della factory durante la composizione)

Fase 2: fase di layout

La fase di layout è suddivisa in due sottofasi distinte con ambiti di invalidazione separati:

Passaggio 2A: misurazione

Determina le dimensioni (width, height) e i vincoli. Lo stato letto qui attiva la nuova misurazione e il nuovo posizionamento:

  • Modifier.layout { measurable, constraints -> ... }: codice prima layout(w, h) viene eseguito durante la misurazione.

Passaggio 2B: callback di posizionamento e layout

Determina la posizione delle coordinate (x, y). Lo stato letto qui attiva solo il riposizionamento (saltando la misurazione e la composizione):

  • Modifier.offset { IntOffset(x, y) } (lambda overload)
  • Modifier.absoluteOffset { IntOffset(x, y) } (lambda overload)
  • Modifier.layout { ... layout(w, h) { placeable.place(x, y) } }: codice all'interno del blocco layout(w, h) { ... }.
  • Modifier.onPlaced { layoutCoordinates -> ... }: viene richiamato dopo che le coordinate del genitore vengono determinate durante il posizionamento.
  • Modifier.onSizeChanged { intSize -> ... }: Richiamato al termine della misurazione del layout se la dimensione è cambiata.
  • Modifier.onGloballyPositioned { layoutCoordinates -> ... }: Richiamato al termine dell'intero passaggio di layout della finestra.

Fase 3: fase di disegno

Questi modificatori vengono eseguiti durante il disegno del canvas. Lo stato letto all'interno di questi blocchi salta sia la composizione che il layout ed esegue solo il passaggio di disegno:

  • Modifier.graphicsLayer { ... }:
    • Proprietà aggiornate in Lambda: alpha, translationX, translationY, scaleX, scaleY, rotationX, rotationY, rotationZ, shadowElevation, shape, clip, renderEffect, transformOrigin.
  • Modifier.drawBehind { ... }:
    • Disegna i comandi canvas dietro i contenuti componibili.
  • Modifier.drawWithContent { ... }:
    • Controlla l'ordine di disegno con drawContent().
  • Modifier.drawWithCache { ... }:
    • Il blocco esterno viene eseguito in base alle modifiche alle dimensioni o al layout per memorizzare nella cache gli oggetti Path, Paint o Brush; onDrawBehind o onDrawWithContent viene eseguito a ogni disegno del frame.

Al di fuori del ciclo di ricomposizione: modificatori di osservazione

Alcuni modificatori operano al di fuori delle tre fasi del frame per gestire l'accessibilità, l'input dell'utente e le osservazioni del ciclo di vita.

Semantica e accessibilità

Elabora le proprietà semantiche per i servizi di accessibilità (TalkBack) e i test:

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

Input, gesti ed eventi

Funziona al di fuori della pipeline di rendering dei frame trifase, ricevendo eventi di movimento del sistema operativo e interazioni dell'utente:

  • 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 -> ... }: il callback viene richiamato quando la visibilità di un elemento componibile cambia dopo il ritardo configurato, in una coroutine.

Riferimento rapido: fase di valore e fase lambda

La lettura di un valore di stato in una lambda posticipa la lettura a una fase successiva, che salta le fasi precedenti quando lo stato cambia:

Modificatore / pattern Valore diretto (composizione) Variante Lambda (fase posticipata) Quando lo stato cambia
Offset Modifier.offset(x, y) Modifier.offset { IntOffset(x, y) } Layout (posizionamento) (salta la composizione)
Alpha / Opacità Modifier.alpha(alpha) Modifier.graphicsLayer { this.alpha = alpha } Disegno (salta Composizione e layout)
Rotazione Modifier.rotate(degrees) Modifier.graphicsLayer { rotationZ = degrees } Disegno (salta Composizione e layout)
Scala Modifier.scale(scale) Modifier.graphicsLayer { scaleX = s; scaleY = s } Disegno (salta Composizione e layout)
Translation Modifier.padding(...) Modifier.graphicsLayer { translationX = ... } Disegno (salta Composizione e layout)
Colore sfondo Modifier.background(color) Modifier.drawBehind { drawRect(color) } Disegno (salta Composizione e layout)
Scorrimento / Parallasse Modifier.offset(scroll.dp) Modifier.offset { IntOffset(0, scroll) } Layout (posizionamento) (salta la composizione)

Mappatura dell'interfaccia Modifier.Node

Per i modificatori personalizzati che utilizzano l'API Modifier.Node ad alte prestazioni, le fasi vengono mappate direttamente alle interfacce delle funzionalità dei nodi:

Fase Interfaccia Modifier.Node Metodi principali
Layout (Misura e posiziona) LayoutModifierNode measure(measurable, constraints)
Layout (coordinate globali) GlobalPositionAwareModifierNode onGloballyPositioned(coordinates)
Layout (posizionamento) LayoutAwareModifierNode onRemeasured(size), onPlaced(coordinates)
Disegno DrawModifierNode draw(ContentDrawScope)
Input / Puntatore PointerInputModifierNode onPointerEvent(...), onCancelPointerInput()
Semantica SemanticsModifierNode applySemantics(SemanticsPropertyReceiver)
Messa a fuoco FocusEventModifierNode onFocusEvent(focusState)