In Jetpack Compose werden Modifikatoren in verschiedenen Phasen ausgeführt. Die folgende Aufschlüsselung zeigt, zu welcher Phase gängige Modifizierer gehören und wann ihre Argumente oder Lambdas ausgewertet werden.
Phase 1: Kompositionsphase
Mit diesen Modifikatoren werden Argumente synchron im @Composable-Body ausgewertet. Jeder hier gelesene Zustand registriert eine Abhängigkeit vom Bereich für den Neustart der komponierbaren Funktion und löst bei Änderung eine vollständige Neukomposition aus.
- Statische Dimensions- und Größenanpassungsmodifizierer:
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)(inRowScopeoderColumnScope)Modifier.width(IntrinsicSize.Min / Max)Modifier.height(IntrinsicSize.Min / Max)
- Statischer Abstand und Insets:
Modifier.padding(all = dp),Modifier.padding(start, top, end, bottom)Modifier.windowInsetsPadding(insets),Modifier.statusBarsPadding()
- Visuelle Modifikatoren für Direktwerte:
Modifier.alpha(float)(liest den Status während der Komposition)Modifier.rotate(degrees)(liest den Status während der Komposition)Modifier.scale(scaleX, scaleY)(liest den Status während der Komposition)Modifier.background(color = Color, shape = Shape)Modifier.border(width, color, shape)Modifier.shadow(elevation, shape)Modifier.clip(shape)Modifier.blur(radius)
- Modifizierer für statische Positionen:
Modifier.offset(x = dp, y = dp)(direct value overload)Modifier.absoluteOffset(x = dp, y = dp)
- Dynamische zusammensetzbare Modifizierer:
Modifier.composed { ... }(führt den Factory-Body während der Komposition aus)
Phase 2: Layoutphase
Die Layoutphase ist in zwei separate Teilschritte mit separaten Invalidierungsbereichen unterteilt:
Schritt 2A: Messung
Bestimmt die Größe (width, height) und die Einschränkungen. Wenn hier ein Status gelesen wird, wird eine erneute Analyse und Platzierung ausgelöst:
Modifier.layout { measurable, constraints -> ... }: Code vorlayout(w, h)wird während der Messung ausgeführt.
Schritt 2B: Callbacks für Platzierung und Layout
Bestimmt die Koordinatenposition (x, y). Der hier gelesene Status löst nur das erneute Platzieren aus (Messung und Zusammensetzung werden übersprungen):
Modifier.offset { IntOffset(x, y) }(Lambda-Überlastung)Modifier.absoluteOffset { IntOffset(x, y) }(Lambda-Überlastung)Modifier.layout { ... layout(w, h) { placeable.place(x, y) } }: Code imlayout(w, h) { ... }-Block.Modifier.onPlaced { layoutCoordinates -> ... }: Wird aufgerufen, nachdem die übergeordneten Koordinaten während der Platzierung ermittelt wurden.Modifier.onSizeChanged { intSize -> ... }: Wird nach Abschluss der Layoutmessung aufgerufen, wenn sich die Größe geändert hat.Modifier.onGloballyPositioned { layoutCoordinates -> ... }: Wird aufgerufen, nachdem der gesamte Layoutdurchlauf des Fensters abgeschlossen ist.
Phase 3: Ziehungsphase
Diese Modifikatoren werden während des Zeichnens des Canvas ausgeführt. Wenn der Status in diesen Blöcken gelesen wird, werden sowohl die Komposition als auch das Layout übersprungen und nur der Zeichenvorgang wird ausgeführt:
Modifier.graphicsLayer { ... }:- In der Lambda-Funktion aktualisierte Attribute:
alpha,translationX,translationY,scaleX,scaleY,rotationX,rotationY,rotationZ,shadowElevation,shape,clip,renderEffect,transformOrigin.
- In der Lambda-Funktion aktualisierte Attribute:
Modifier.drawBehind { ... }:- Zeichnet Canvas-Befehle hinter den zusammensetzbaren Inhalten.
Modifier.drawWithContent { ... }:- Steuert die Zeichenreihenfolge mit
drawContent().
- Steuert die Zeichenreihenfolge mit
Modifier.drawWithCache { ... }:- Der äußere Block wird bei Größen- oder Layoutänderungen ausgeführt, um
Path-,Paint- oderBrush-Objekte im Cache zu speichern.onDrawBehindoderonDrawWithContentwird bei jedem Rendern eines Frames ausgeführt.
- Der äußere Block wird bei Größen- oder Layoutänderungen ausgeführt, um
Außerhalb des Recomposition-Loops – Beobachtungsmodifikatoren
Einige Modifikatoren werden außerhalb der drei Frame-Phasen ausgeführt, um Barrierefreiheit, Nutzereingaben und Lebenszyklusbeobachtungen zu verarbeiten.
Semantik und Bedienungshilfen
Verarbeitet semantische Eigenschaften für Bedienungshilfen (TalkBack) und Tests:
Modifier.semantics { ... }Modifier.clearAndSetSemantics { ... }
Eingabe, Gesten und Ereignisse
Wird außerhalb der dreiphasigen Frame-Rendering-Pipeline ausgeführt und empfängt OS-Bewegungsereignisse und Nutzerinteraktionen:
Modifier.pointerInput(key) { detectTapGestures { ... } }/detectDragGestures/awaitPointerEventScopeModifier.clickable(enabled, onClickLabel) { ... }Modifier.combinedClickable { ... }Modifier.toggleable { ... }Modifier.selectable { ... }Modifier.draggable(...)/Modifier.scrollable(...)/Modifier.draggable2D(...)Modifier.onFocusChanged { focusState -> ... }Modifier.onKeyEvent { keyEvent -> ... }Modifier.onVisibilityChanged { isVisible -> ... }: Der Callback wird in einer Coroutine aufgerufen, wenn sich die Sichtbarkeit eines Composables nach der konfigurierten Verzögerung ändert.
Kurzübersicht: Wert- im Vergleich zur Lambda-Phase
Wenn Sie einen Statuswert in einem Lambda lesen, wird das Lesen auf eine spätere Phase verschoben. Dadurch werden frühere Phasen übersprungen, wenn sich dieser Status ändert:
| Modifikator / Muster | Direkter Wert (Zusammensetzung) | Lambda-Variante (aufgeschobene Phase) | Wenn sich der Status ändert |
|---|---|---|---|
| Offset | Modifier.offset(x, y) |
Modifier.offset { IntOffset(x, y) } |
Layout (Placement) (Skips Composition) |
| Alpha / Deckkraft | Modifier.alpha(alpha) |
Modifier.graphicsLayer { this.alpha = alpha } |
Zeichnen (Komposition und Layout werden übersprungen) |
| Rotation | Modifier.rotate(degrees) |
Modifier.graphicsLayer { rotationZ = degrees } |
Zeichnen (Komposition und Layout werden übersprungen) |
| Scale | Modifier.scale(scale) |
Modifier.graphicsLayer { scaleX = s; scaleY = s } |
Zeichnen (Komposition und Layout werden übersprungen) |
| Translation | Modifier.padding(...) |
Modifier.graphicsLayer { translationX = ... } |
Zeichnen (Komposition und Layout werden übersprungen) |
| Hintergrundfarbe | Modifier.background(color) |
Modifier.drawBehind { drawRect(color) } |
Zeichnen (Komposition und Layout werden übersprungen) |
| Scrollen / Parallaxe | Modifier.offset(scroll.dp) |
Modifier.offset { IntOffset(0, scroll) } |
Layout (Placement) (Skips Composition) |
Modifier.Node-Schnittstellenzuordnung
Bei benutzerdefinierten Modifikatoren, die die leistungsstarke Modifier.Node API verwenden, werden Phasen direkt den Schnittstellen für Knotenfunktionen zugeordnet:
| Phase | Modifier.Node-Schnittstelle |
Kernmethoden |
|---|---|---|
| Layout (Messen und platzieren) | LayoutModifierNode |
measure(measurable, constraints) |
| Layout (globale Koordinaten) | GlobalPositionAwareModifierNode |
onGloballyPositioned(coordinates) |
| Layout (Placement) | LayoutAwareModifierNode |
onRemeasured(size), onPlaced(coordinates) |
| Zeichnung | DrawModifierNode |
draw(ContentDrawScope) |
| Eingabe / Zeiger | PointerInputModifierNode |
onPointerEvent(...), onCancelPointerInput() |
| Semantik | SemanticsModifierNode |
applySemantics(SemanticsPropertyReceiver) |
| Fokus | FocusEventModifierNode |
onFocusEvent(focusState) |