Animazioni riquadri

Puoi animare i riquadri in diversi modi, tra cui:

Mostra transizione di tipo Sposta

Per mostrare un'interpolazione uniforme da un valore all'altro, puoi attivare l'interpolazione animazioni di un elemento, come mostrato nel seguente codice snippet:

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.
    );
}

Imposta la direzione dell'arco

Se il riquadro contiene un arco, potresti non volere che la linea o il testo dell'arco siano sempre crescono nella direzione del testo predefinita per la lingua scelta dall'utente. Per specificare una direzione di crescita arco, utilizza le API ArcDirection:

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()
    );
}

Mostra una dissolvenza uniforme o una slide

Per indicare più chiaramente che un elemento appare o scompare in un riquadro, o per mostrare in modo più discreto un cambio di passo nel valore di un riquadro, usa dissolvenza e scorri nelle animazioni dei riquadri.

Se un layout di riquadri contiene un elemento il cui valore cambia, il riquadro mostra l'animazione di uscita dell'elemento, poi aggiorna il layout e mostra il valore l'animazione.

Transizioni di dissolvenza

Il seguente snippet di codice illustra come eseguire una dissolvenza in entrata e in uscita utilizzando i metodi helper di DefaultContentTransitions. A definire oggetti FadeInTransition e FadeOutTransition personalizzati, richiamare setFadeIn() e setFadeOut(), rispettivamente, nella transizione metodi di impostazione.

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()
    );
}

Transizioni slide

Questo altro snippet di codice illustra come eseguire le operazioni di scorrimento in entrata e in uscita utilizzando i metodi helper di DefaultContentTransitions. Tu puoi anche definire oggetti SlideInTransition e SlideOutTransition personalizzati chiamata setSlideIn() e setSlideOut(), rispettivamente, nella metodi di impostazione della transizione.

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()
    );
}

Mostra una trasformazione

Per richiamare l'attenzione su un elemento o un'area specifici di un riquadro, puoi applicare più tipi di trasformazioni, tra cui rotazione, scalabilità e traslazione.

Molti valori in virgola mobile associati alle trasformazioni accettano espressioni dinamiche, che ti consentono di animare queste trasformazioni.

Rotazione

Per eseguire una rotazione in senso orario attorno a un punto pivot personalizzabile, utilizza il codice simile al seguente:

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()
);

Scalabilità

Per aumentare o ridurre un elemento in base a fattori di ridimensionamento orizzontale e verticale, usa simile al seguente:

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()
);

Traduzione geometrica

Spostare un elemento di un determinato numero di densità pixel (dp) attraverso lo schermo orizzontalmente o verticalmente, utilizza un codice simile al seguente:

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()
);

Non mostrare informazioni importanti al centro di un'animazione.

Le animazioni vengono disabilitate in diverse situazioni:

  • Il rendering dei riquadri del sistema potrebbe disattivare le animazioni per tutti i riquadri.
  • In un riquadro è possibile animare solo quattro elementi alla volta. Se provi ad animare con più di quattro elementi contemporaneamente, non tutti mostrano un'animazione.

Nel caso in cui un'animazione sia disabilitata, gli elementi sono statici e mostrano i valore finale dell'animazione. Per questo motivo, non fare affidamento sul comportamento dell'animazione, come la sua durata, per mostrare informazioni importanti.