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 tuile contient un arc, il se peut que la ligne de l'arc ou le texte ne soient pas toujours
s'agrandissent dans l'orientation par défaut du texte 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 appliquer plusieurs types de transformations, y compris la rotation, la mise à l'échelle et la traduction.
De nombreuses valeurs à virgule flottante associées aux transformations acceptent Expressions dynamiques, qui vous permettent d'animer ces transformations.
Rotation
Pour effectuer une rotation dans le sens des aiguilles d'une montre autour d'un point pivot personnalisable, utilisez du code semblable à ce qui suit:
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 selon des 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
Déplacer un élément d'un nombre spécifique de pixels de densité (dp) à 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.