Animationsmodifikatoren und zusammensetzbare Funktionen

Compose verfügt über integrierte zusammensetzbare Funktionen und Modifikatoren für gängige Anwendungsfälle in der Animation.

Integrierte animierte zusammensetzbare Funktionen

Aussehen und Verschwinden mit AnimatedVisibility animieren

<ph type="x-smartling-placeholder">
</ph> Grüne zusammensetzbare Funktion, die sich ein- und ausblenden lässt
Abbildung 1: Darstellung und Verschwinden eines Elements in einer Spalte animieren

Die AnimatedVisibility componable animiert das Erscheinungsbild und das Verschwinden seines Inhalts.

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

Standardmäßig wird der Inhalt durch Ein- und Ausblenden eingeblendet und wieder ausgeblendet, immer kleiner wird. Der Übergang kann angepasst werden, indem EnterTransition und ExitTransition

var visible by remember { mutableStateOf(true) }
val density = LocalDensity.current
AnimatedVisibility(
    visible = visible,
    enter = slideInVertically {
        // Slide in from 40 dp from the top.
        with(density) { -40.dp.roundToPx() }
    } + expandVertically(
        // Expand from the top.
        expandFrom = Alignment.Top
    ) + fadeIn(
        // Fade in with the initial alpha of 0.3f.
        initialAlpha = 0.3f
    ),
    exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
    Text("Hello", Modifier.fillMaxWidth().height(200.dp))
}

Wie Sie im obigen Beispiel sehen, können Sie mehrere EnterTransition-Elemente oder ExitTransition-Objekte mit einem +-Operator an und akzeptiert für jedes optionale um das Verhalten anzupassen. Weitere Informationen finden Sie in den Referenzen.

Beispiele für EnterTransition und ExitTransition

Übergang Übergang
fadeIn
Animation einblenden
fadeOut
Ausblenden (Animation)
slideIn
Einblendungsanimation
slideOut
Animation zum Ausblenden
slideInHorizontally
Animation horizontal einblenden
slideOutHorizontally
Animation horizontal herausziehen
slideInVertically
Animation senkrecht hineinschieben
slideOutVertically
Animation senkrecht herausschieben
scaleIn
Animation vergrößern
scaleOut
Animation mit horizontaler Skalierung
expandIn
In Animation maximieren
shrinkOut
Animation verkleinern
expandHorizontally
Animation horizontal maximieren
shrinkHorizontally
Animation horizontal verkleinern
expandVertically
Animation vertikal maximieren
shrinkVertically
Animation vertikal verkleinern

AnimatedVisibility bietet auch eine Variante mit einer MutableTransitionState. So können Sie eine Animation auslösen, sobald der AnimatedVisibility wird dem Kompositionsbaum hinzugefügt. Sie ist auch nützlich für den Animationsstatus beobachten.

// Create a MutableTransitionState<Boolean> for the AnimatedVisibility.
val state = remember {
    MutableTransitionState(false).apply {
        // Start the animation immediately.
        targetState = true
    }
}
Column {
    AnimatedVisibility(visibleState = state) {
        Text(text = "Hello, world!")
    }

    // Use the MutableTransitionState to know the current animation state
    // of the AnimatedVisibility.
    Text(
        text = when {
            state.isIdle && state.currentState -> "Visible"
            !state.isIdle && state.currentState -> "Disappearing"
            state.isIdle && !state.currentState -> "Invisible"
            else -> "Appearing"
        }
    )
}

Ein- und Ausgang für Kinder animieren

Inhalte unter AnimatedVisibility (direkte oder indirekte Kinder) dürfen die animateEnterExit , um für jeden ein anderes Animationsverhalten anzugeben. Das visuelle Element für jedes dieser untergeordneten Elemente eine Kombination der angegebenen Animationen ist. an der zusammensetzbaren Funktion AnimatedVisibility und den eigenen Eingabe- und zum Beenden von Animationen.

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn(),
    exit = fadeOut()
) {
    // Fade in/out the background and the foreground.
    Box(Modifier.fillMaxSize().background(Color.DarkGray)) {
        Box(
            Modifier
                .align(Alignment.Center)
                .animateEnterExit(
                    // Slide in/out the inner box.
                    enter = slideInVertically(),
                    exit = slideOutVertically()
                )
                .sizeIn(minWidth = 256.dp, minHeight = 64.dp)
                .background(Color.Red)
        ) {
            // Content of the notification…
        }
    }
}

In einigen Fällen kann es sinnvoll sein, dass AnimatedVisibility keine Animationen sodass Kinder ihre eigenen Animationen haben können, animateEnterExit. Geben Sie dazu EnterTransition.None und ExitTransition.None für die zusammensetzbare Funktion AnimatedVisibility

Benutzerdefinierte Animation hinzufügen

Wenn Sie benutzerdefinierte Animationseffekte hinzufügen möchten, die über die integrierten Ein- und Exit-Funktionen hinausgehen, Animationen verwenden, greifen Sie über die transition auf die zugrunde liegende Transition-Instanz zu. innerhalb der Inhalts-Lambda-Funktion für AnimatedVisibility. Beliebige Animationen Status, die der Transition-Instanz hinzugefügt wurden, werden gleichzeitig mit der Eingabetaste ausgeführt und die Animationen von AnimatedVisibility beenden. AnimatedVisibility wartet bis Alle Animationen im Transition sind beendet, bevor der Inhalt entfernt wurde. Für Exit-Animationen, die unabhängig von Transition erstellt wurden (z. B. mit animate*AsState), AnimatedVisibility kann diesen Vorgang nicht berücksichtigen, und kann daher den zusammensetzbaren Inhalt entfernen, bevor er fertig ist.

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn(),
    exit = fadeOut()
) { // this: AnimatedVisibilityScope
    // Use AnimatedVisibilityScope#transition to add a custom animation
    // to the AnimatedVisibility.
    val background by transition.animateColor(label = "color") { state ->
        if (state == EnterExitState.Visible) Color.Blue else Color.Gray
    }
    Box(modifier = Modifier.size(128.dp).background(background))
}

Weitere Informationen zu Transition finden Sie unter updateTransition.

Mit AnimatedContent basierend auf dem Zielstatus animieren

Die AnimatedContent Die Funktion animiert den Inhalt, während er sich basierend auf Zielstatus

Row {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Add")
    }
    AnimatedContent(targetState = count) { targetCount ->
        // Make sure to use `targetCount`, not `count`.
        Text(text = "Count: $targetCount")
    }
}

Beachten Sie, dass Sie immer den Lambda-Parameter verwenden und ihn im Inhalte. Die API verwendet diesen Wert als Schlüssel, um den Inhalt zu identifizieren, angezeigt wird.

Standardmäßig wird der ursprüngliche Inhalt ausgeblendet und dann der Zielinhalt ausgeblendet Dieses Verhalten wird als Überblenden bezeichnet. Ich können Sie dieses Animationsverhalten anpassen, indem Sie ein ContentTransform-Objekt für den transitionSpec-Parameter. Sie können ContentTransform erstellen, indem Sie EnterTransition mit einem ExitTransition mit der Infix-Funktion with. Sie können SizeTransform anwenden an die ContentTransform durch Anhängen mit dem Infix-Funktion using.

AnimatedContent(
    targetState = count,
    transitionSpec = {
        // Compare the incoming number with the previous number.
        if (targetState > initialState) {
            // If the target number is larger, it slides up and fades in
            // while the initial (smaller) number slides up and fades out.
            slideInVertically { height -> height } + fadeIn() with
                slideOutVertically { height -> -height } + fadeOut()
        } else {
            // If the target number is smaller, it slides down and fades in
            // while the initial number slides down and fades out.
            slideInVertically { height -> -height } + fadeIn() with
                slideOutVertically { height -> height } + fadeOut()
        }.using(
            // Disable clipping since the faded slide-in/out should
            // be displayed out of bounds.
            SizeTransform(clip = false)
        )
    }
) { targetCount ->
    Text(text = "$targetCount")
}

EnterTransition definiert, wie der Zielinhalt angezeigt werden soll, und ExitTransition legt fest, wie der ursprüngliche Inhalt verschwinden soll. Außerdem EnterTransition- und ExitTransition-Funktionen, die für AnimatedVisibility, AnimatedContent Angebote slideIntoContainer und slideOutOfContainer. Dies sind praktische Alternativen zu slideInHorizontally/Vertically und slideOutHorizontally/Vertically, die die Entfernung der Folie berechnen anhand die Größen des ursprünglichen Inhalts und des Zielinhalts AnimatedContent Inhalt.

SizeTransform definiert, wie die sollte zwischen dem anfänglichen Inhalt und dem Zielinhalt animiert werden. Du hast sowohl auf die Anfangs- als auch auf die Zielgröße zugreifen, Animation. SizeTransform legt auch fest, ob der Inhalt zugeschnitten werden soll. an die Komponentengröße anpassen.

var expanded by remember { mutableStateOf(false) }
Surface(
    color = MaterialTheme.colorScheme.primary,
    onClick = { expanded = !expanded }
) {
    AnimatedContent(
        targetState = expanded,
        transitionSpec = {
            fadeIn(animationSpec = tween(150, 150)) with
                fadeOut(animationSpec = tween(150)) using
                SizeTransform { initialSize, targetSize ->
                    if (targetState) {
                        keyframes {
                            // Expand horizontally first.
                            IntSize(targetSize.width, initialSize.height) at 150
                            durationMillis = 300
                        }
                    } else {
                        keyframes {
                            // Shrink vertically first.
                            IntSize(initialSize.width, targetSize.height) at 150
                            durationMillis = 300
                        }
                    }
                }
        }
    ) { targetExpanded ->
        if (targetExpanded) {
            Expanded()
        } else {
            ContentIcon()
        }
    }
}

Ein- und Ausblenden von Kindern animieren

Genau wie AnimatedVisibility wird die animateEnterExit ist im Content-Lambda von AnimatedContent verfügbar. Verwenden EnterAnimation und ExitAnimation auf die direkten oder indirekten für Kinder separat ansehen.

Benutzerdefinierte Animation hinzufügen

Genau wie bei AnimatedVisibility ist das Feld transition im Lambda von AnimatedContent. Hiermit können Sie eine benutzerdefinierte Animation erstellen. Effekt, der gleichzeitig mit dem AnimatedContent-Übergang ausgeführt wird. Weitere Informationen finden Sie unter updateTransition.

Mit Crossfade zwischen zwei Layouts animieren

Crossfade animiert zwischen zwei Layouts mit einer Überblendungsanimation. Durch Umschalten Wert, der an den Parameter current übergeben wird, wird der Inhalt durch eine überblendende Animation.

var currentPage by remember { mutableStateOf("A") }
Crossfade(targetState = currentPage) { screen ->
    when (screen) {
        "A" -> Text("Page A")
        "B" -> Text("Page B")
    }
}

Integrierte Animationsmodifikatoren

Zusammensetzbare Größenänderungen mit animateContentSize animieren

<ph type="x-smartling-placeholder">
</ph> Grüne zusammensetzbare Funktion, deren Größe animiert wird, ändert sich reibungslos.
Abbildung 2: Zusammensetzbare Animation zwischen einer kleinen und einer größeren Größe

Der animateContentSize-Modifikator animiert eine Größenänderung.

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

Animationen zu Listenelementen

Wenn Sie die Neuanordnung von Elementen innerhalb einer Lazy-Liste oder eines Lazy-Rasters animieren möchten, sehen Sie sich die Dokumentation zur Animation von Lazy-Layoutelementen