Vous pouvez animer vos cartes de différentes manières, par exemple :
- Transitions "Balayage" à l'aide d'animations d'interpolation
- Fondu et glissement fluides dans une carte et en dehors de celle-ci
Afficher une transition "Balayage"
Pour afficher un balayage fluide d'une valeur à une autre, vous pouvez activer les animations d'interpolation pour un élément, comme illustré dans l'extrait de code suivant :
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. ); }
Définir la direction de l'arc
Si votre carte contient un arc, vous ne souhaitez peut-être pas que la ligne de l'arc ou le texte grandissent toujours dans la direction du texte par défaut pour la langue choisie par l'utilisateur. Pour spécifier une direction de croissance d'arc, utilisez les 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() ); }
Afficher un fondu ou un glissement fluide
Pour indiquer plus clairement qu'un élément apparaît ou disparaît dans une carte, ou pour afficher plus subtilement un changement dans la valeur d'une carte, utilisez des effets de fondu et de glissement dans vos animations de carte.
Si une mise en page de carte contient un élément dont la valeur change, la carte affiche l'animation de sortie de l'élément, puis met à jour la mise en page et affiche l'animation d'entrée de l'élément.
Transitions "Fondu"
L'extrait de code suivant montre comment effectuer des transitions de fondu en entrée et en sortie à l'aide des méthodes d'assistance de DefaultContentTransitions
. Pour définir des objets FadeInTransition
et FadeOutTransition
personnalisés, appelez respectivement setFadeIn()
et setFadeOut()
dans les méthodes setter de la transition.
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() ); }
Transitions "Glissement"
Cet autre extrait de code montre comment effectuer des transitions de glissement en entrée et en sortie à l'aide des méthodes d'assistance de DefaultContentTransitions
. Vous pouvez également définir des objets SlideInTransition
et SlideOutTransition
personnalisés en appelant respectivement setSlideIn()
et setSlideOut()
dans les méthodes setter de la transition.
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() ); }
Afficher une transformation
Pour attirer l'attention sur un élément ou une zone spécifique d'une carte, vous pouvez lui appliquer plusieurs types de transformations, y compris la rotation, la mise à l'échelle et la traduction.
De nombreuses valeurs à virgule flottante associées à des transformations acceptent les expressions dynamiques, ce qui vous permet d'animer ces transformations.
Rotation
Pour effectuer une rotation dans le sens des aiguilles d'une montre autour d'un point pivot personnalisable, utilisez un code semblable à celui-ci:
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() );
Mettre à l'échelle
Pour augmenter ou réduire un élément en fonction de facteurs de scaling horizontal et vertical, utilisez un code semblable à celui-ci:
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() );
Traduction géométrique
Pour déplacer un élément d'un nombre spécifique de pixels de densité (dp) sur l'écran horizontalement ou verticalement, utilisez un code semblable à celui-ci:
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() );
Ne pas afficher d'informations importantes au milieu d'une animation
Les animations sont parfois désactivées :
- Le rendu des cartes du système peut désactiver les animations pour toutes les cartes.
- Une carte ne peut animer que quatre éléments à la fois. Si vous essayez d'animer plus de quatre éléments en même temps, tous n'affichent pas une animation.
Dans le cas où une animation est désactivée, les éléments sont statiques et affichent la valeur de fin de l'animation. Pour cette raison, ne comptez pas sur le comportement de l'animation, comme sa durée, pour afficher des informations importantes.