Kachelanimationen

Sie können Ihre Kacheln auf verschiedene Arten animieren. Dazu gehören:

„Erledigen“-Übergang anzeigen

Wenn Sie für ein Element Tween-Animationen aktivieren möchten, können Sie den Übergang von einem Wert zum anderen gleichmäßig ausführen, wie im folgenden Code-Snippet gezeigt:

Kotlin

private val defaultValue = 0f
private var startValue = 15f
private var endValue = 105f
private val animationDurationInMillis = 2000f // 2 seconds

override fun onTileRequest(requestParams: TileRequest) =
    Futures.immediateFuture(
        // Add timeline and layout containers. CircularProgressIndicator is an
        // inner element of those containers.
        CircularProgressIndicator.Builder()
            .setProgress(
                FloatProp.Builder(/* static value */ 0.25f)
                    .setDynamicValue(
                    // Or you can use some other dynamic object, for example
                    // from the platform and then at the end of expression
                    // add animate().
                        DynamicFloat.animate(startValue, endValue,
                            AnimationSpec.Builder()
                                .setAnimationParameters(
                                    AnimationParameters.Builder()
                                        .setDurationMillis(animationDurationInMillis)
                                        .build()
                                ).build()
                        )
                    ).build()
            ).build()
        // Finish building all elements that contain CircularProgressIndicator.
    )

Java

private float defaultValue = 0f;
private float startValue = 15f;
private float endValue = 105f;
private float animationDurationInMillis = 2000f; // 2 seconds

@Override
protected ListenableFuture<Tile> onTileRequest(
       @NonNull TileRequest requestParams
) {
    return Futures.immediateFuture(
        // Add timeline and layout containers. CircularProgressIndicator is an
        // inner element of those containers.
        new CircularProgressIndicator.Builder()
            .setProgress(
                new FloatProp.Builder(/* static value */ 0.25f)
                    .setDynamicValue(
                    // Or you can use some other dynamic object, for example
                    // from the platform and then at the end of expression
                    // add animate().
                        DynamicFloat.animate(startValue, endValue,
                            new AnimationSpec.Builder()
                                .setAnimationParameters(
                                    new AnimationParameters.Builder()
                                        .setDurationMillis(animationDurationInMillis)
                                        .build()
                                ).build()
                        )
                    ).build()
            ).build()
        // Finish building all elements that contain CircularProgressIndicator.
    );
}

Bogenrichtung festlegen

Wenn Ihre Kachel einen Bogen enthält, möchten Sie möglicherweise nicht, dass die Bogenlinie oder der Text immer in die Standardtextrichtung der vom Nutzer gewählten Sprache erweitert werden. Verwenden Sie die ArcDirection APIs, um eine Wachstumsrichtung für den Bogen festzulegen:

Kotlin

@OptIn(ProtoLayoutExperimental::class)
public override fun onTileRequest(
        requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {
    return Futures.immediateFuture(Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            EdgeContentLayout.Builder(deviceParameters)
                .setEdgeContent(
                    Arc.Builder()
                        // Arc should always grow clockwise.
                        .setArcDirection(LayoutElementBuilders.ARC_DIRECTION_CLOCKWISE)
                        .addContent(
                            ArcLine.Builder()
                            // Set color, length, thickness, and more.
                            // Arc should always grow clockwise.
                            .setArcDirection(
                                LayoutElementBuilders.ARC_DIRECTION_CLOCKWISE)
                            .build()
                        ).build()
                ).build())
        ).build()
    )
}

Java

@OptIn(markerClass = ProtoLayoutExperimental.class)
@NonNull
@Override
protected ListenableFuture<Tile> onTileRequest(
        @NonNull RequestBuilders.TileRequest requestParams
) {
    return Futures.immediateFuture(new Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            new EdgeContentLayout.Builder(deviceParameters)
                .setEdgeContent(
                    new Arc.Builder()
                        // Arc should always grow clockwise.
                        .setArcDirection(LayoutElementBuilders.ARC_DIRECTION_CLOCKWISE)
                        .addContent(
                            new ArcLine.Builder()
                            // Set color, length, thickness, and more.
                            // Arc should always grow clockwise.
                            .setArcDirection(
                                LayoutElementBuilders.ARC_DIRECTION_CLOCKWISE)
                            .build())
                        .build())
                .build()))
        .build()
    );
}

Langsames Überblenden oder Glätten anzeigen

Um deutlicher anzuzeigen, dass ein Element in einer Kachel erscheint oder verschwindet, oder um eine Schrittänderung im Wert einer Kachel deutlicher darzustellen, verwenden Sie in Ihren Kachelanimationen Effekte zum Ein- und Ausblenden.

Wenn ein Kachellayout ein Element enthält, dessen Wert sich ändert, zeigt die Kachel die Exit-Animation des Elements an, aktualisiert dann das Layout und zeigt die Eingabeanimation des Elements an.

Übergänge ausblenden

Das folgende Code-Snippet zeigt, wie Ein- und Ausblendungen mit den Hilfsmethoden von DefaultContentTransitions ausgeführt werden. Um benutzerdefinierte FadeInTransition- und FadeOutTransition-Objekte zu definieren, rufen Sie in den Transition-Setter-Methoden setFadeIn() bzw. setFadeOut() auf.

Kotlin

@OptIn(ProtoLayoutExperimental::class)
public override fun onTileRequest(
        requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {
    // Assumes that you've defined a custom helper method called
    // getTileTextToShow().
    val tileText = getTileTextToShow()
    return Futures.immediateFuture(Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            Text.Builder(this, tileText)
                .setModifiers(
                    ModifiersBuilders.Modifiers.Builder()
                        .setContentUpdateAnimation(AnimatedVisibility.Builder()
                            .setEnterTransition(
                                    DefaultContentTransitions.fadeIn())
                            .setExitTransition(
                                    DefaultContentTransitions.fadeOut()
                            ).build())
                ).build())
        ).build()
    )
}

Java

@OptIn(markerClass = ProtoLayoutExperimental.class)
@NonNull
@Override
protected ListenableFuture<Tile> onTileRequest(
        @NonNull RequestBuilders.TileRequest requestParams
) {
    // Assumes that you've defined a custom helper method called
    // getTileTextToShow().
    String tileText = getTileTextToShow();

    return Futures.immediateFuture(new Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            new Text.Builder(this, tileText)
                .setModifiers(
                    new ModifiersBuilders.Modifiers.Builder()
                        .setContentUpdateAnimation(new AnimatedVisibility.Builder()
                            .setEnterTransition(
                                    DefaultContentTransitions.fadeIn())
                            .setExitTransition(
                                    DefaultContentTransitions.fadeOut())
                            .build())
                .build()))
        .build()
    );
}

Folienübergänge

In diesem anderen Code-Snippet wird gezeigt, wie mit den Hilfsmethoden von DefaultContentTransitions Slide-in- und Slide-out-Übergänge durchgeführt werden. Sie können auch benutzerdefinierte SlideInTransition- und SlideOutTransition-Objekte definieren, indem Sie setSlideIn() bzw. setSlideOut() in den Transition-Setter-Methoden aufrufen.

Kotlin

@OptIn(ProtoLayoutExperimental::class)
public override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {
    // Assumes that you've defined a custom helper method called
    // getTileTextToShow().
    val tileText = getTileTextToShow()
    return Futures.immediateFuture(Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            Text.Builder(this, tileText)
                .setModifiers(
                    Modifiers.Builder()
                         .setContentUpdateAnimation(AnimatedVisibility.Builder()
                            .setEnterTransition(
                                DefaultContentTransitions.slideIn(
                                    SLIDE_DIRECTION_LEFT_TO_RIGHT)
                            ).setExitTransition(
                                DefaultContentTransitions.slideOut(
                                    SLIDE_DIRECTION_LEFT_TO_RIGHT)
                            ).build()
                        ).build()
                ).build()
        )).build()
    )
}

Java

@OptIn(markerClass = ProtoLayoutExperimental.class)
@NonNull
@Override
protected ListenableFuture<Tile> onTileRequest(
        @NonNull RequestBuilders.TileRequest requestParams
) {
    // Assumes that you've defined a custom helper method called
    // getTileTextToShow().
    String tileText = getTileTextToShow();
    return Futures.immediateFuture(Tile.Builder()
        .setResourcesVersion(RESOURCES_VERSION)
        .setTileTimeline(Timeline.fromLayoutElement(
            new Text.Builder(this, tileText)
                .setModifiers(
                    new Modifiers.Builder()
                        .setContentUpdateAnimation(
                            new AnimatedVisibility.Builder()
                                .setEnterTransition(
                                    DefaultContentTransitions.slideIn(
                                        SLIDE_DIRECTION_LEFT_TO_RIGHT))
                                .setExitTransition(
                                    DefaultContentTransitions.slideOut(
                                        SLIDE_DIRECTION_LEFT_TO_RIGHT))
                                .build())
                        .build())
                .build()))
        .build()
    );
}

Transformation anzeigen

Sie können verschiedene Arten von Transformationen darauf anwenden, um die Aufmerksamkeit auf ein bestimmtes Element oder einen bestimmten Bereich in einer Kachel zu lenken, einschließlich Rotation, Skalierung und Umwandlung.

Viele Gleitkommawerte im Zusammenhang mit Transformationen akzeptieren dynamische Ausdrücke, mit denen Sie diese Transformationen animieren können.

Drehung

Um einen anpassbaren Drehpunkt im Uhrzeigersinn zu drehen, verwenden Sie Code ähnlich dem folgenden:

Kotlin

// Last line in your onTileRequest() method implementation.
return Futures.immediateFuture(Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        Text.Builder(this, someTileText)
            .setModifiers(
                    ModifiersBuilders.Transformation.Builder()
                        // Set the pivot point 50 dp from the left edge
                        // and 100 dp from the top edge of the screen.
                        .setPivotX(dp(50))
                        .setPivotY(dp(100))
                        // Rotate the element 45 degrees clockwise.
                        .setRotation(
                            degrees(45f)
                        ).build()
            ).build())
    ).build()
)

Java

// Last line in your onTileRequest() method implementation.
return Futres.immediateFuture(new Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        new Text.Builder(this, someTileText)
            .setModifiers(
                    new ModifiersBuilders.Transformation.Builder()
                        // Set the pivot point 50 dp from the left edge
                        // and 100 dp from the top edge of the screen.
                        .setPivotX(dp(50))
                        .setPivotY(dp(100))
                        // Rotate the element 45 degrees clockwise.
                        .setRotation(
                            degrees(45f))
                        .build())
            .build()))
    .build()
);

Skalierung

Wenn Sie ein Element um horizontale und vertikale Skalierungsfaktoren vergrößern oder verkleinern möchten, verwenden Sie Code ähnlich dem folgenden:

Kotlin

// Last line in your onTileRequest() method implementation.
return Futures.immediateFuture(Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        Text.Builder(this, someTileText)
            .setModifiers(
                    ModifiersBuilders.Transformation.Builder()
                        // Set the pivot point 50 dp from the left edge
                        // and 100 dp from the top edge of the screen.
                        .setPivotX(dp(50))
                        .setPivotY(dp(100))
                        // Shrink the element by a scale factor
                        // of 0.5 horizontally and 0.75 vertically.
                        .setScaleX(TypeBuilders.FloatProp.Builder(0.5f)
                                .build())
                        .setScaleY(TypeBuilders.FloatProp.Builder(0.75f)
                                .build()
                        ).build()
            ).build())
    ).build()
)

Java

// Last line in your onTileRequest() method implementation.
return Futres.immediateFuture(new Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        new Text.Builder(this, someTileText)
            .setModifiers(
                    new ModifiersBuilders.Transformation.Builder()
                        // Set the pivot point 50 dp from the left edge
                        // and 100 dp from the top edge of the screen.
                        .setPivotX(dp(50))
                        .setPivotY(dp(100))
                        // Shrink the element by a scale factor
                        // of 0.5 horizontally and 0.75 vertically.
                        .setScaleX(new TypeBuilders.FloatProp.Builder(0.5f)
                                .build())
                        .setScaleY(new TypeBuilders.FloatProp.Builder(0.75f)
                                .build())
                        .build())
            .build()))
    .build()
);

Geometrische Übersetzung

Wenn Sie ein Element horizontal oder vertikal um eine bestimmte Anzahl von Pixeldichten (dp) über den Bildschirm verschieben möchten, verwenden Sie folgenden Code:

Kotlin

// Last line in your onTileRequest() method implementation.
return Futures.immediateFuture(Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        Text.Builder(this, someTileText)
            .setModifiers(
                    ModifiersBuilders.Transformation.Builder()
                        // Translate (move) the element 60 dp to the right
                        // and 80 dp down.
                        .setTranslationX(dp(60))
                        .setTranslationY(dp(80))
                        .build()
            ).build())
    ).build()
)

Java

// Last line in your onTileRequest() method implementation.
return Futres.immediateFuture(new Tile.Builder()
    .setResourcesVersion(RESOURCES_VERSION)
    .setTileTimeline(Timeline.fromLayoutElement(
        new Text.Builder(this, someTileText)
            .setModifiers(
                    new ModifiersBuilders.Transformation.Builder()
                        // Translate (move) the element 60 dp to the right
                        // and 80 dp down.
                        .setTranslationX(dp(60))
                        .setTranslationY(dp(80))
                        .build())
            .build()))
    .build()
);

Wichtige Informationen nicht mitten in einer Animation anzeigen

Animationen sind in verschiedenen Situationen deaktiviert:

  • Das Kachel-Rendering des Systems deaktiviert möglicherweise Animationen für alle Kacheln.
  • Eine Kachel kann nur vier Elemente gleichzeitig animieren. Wenn Sie versuchen, mehr als vier Elemente gleichzeitig zu animieren, wird nicht für alle eine Animation angezeigt.

Wenn eine Animation deaktiviert ist, sind die Elemente statisch und zeigen den Endwert der Animation an. Verlassen Sie sich daher nicht auf das Verhalten der Animation, z. B. auf ihre Dauer, um wichtige Informationen anzuzeigen.