Kacheln unterstützen verschiedene Animationsansätze, darunter die folgenden:
- Sweep-Übergänge mit Tween-Animationen.
- Flüssige Ein- und Ausblendung von Kacheln.
- Lottie-Animationen.
Wischblende einfügen
Wenn Sie einen sanften Übergang von einem Wert zu einem anderen darstellen möchten, können Sie Tween-Animationen für ein Element aktivieren, wie im folgenden Code-Snippet gezeigt:
private var startValue = 15f private var endValue = 105f private val animationDurationInMillis = 2000L // 2 seconds override fun onTileRequest(requestParams: RequestBuilders.TileRequest): ListenableFuture<Tile> { val circularProgressIndicator = 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() return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(Timeline.fromLayoutElement(circularProgressIndicator)) .build() ) }
Richtung des Bogens festlegen
Wenn Ihre Kachel einen Bogen enthält, soll die Bogenlinie oder der Text möglicherweise nicht immer in der Standardtextrichtung für die vom Nutzer ausgewählte Sprache wachsen. Verwenden Sie die ArcDirection
-APIs, um eine Richtung für das Wachstum des Bogens anzugeben:
public override fun onTileRequest( requestParams: RequestBuilders.TileRequest ): ListenableFuture<Tile> { return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( EdgeContentLayout.Builder(deviceParameters) .setResponsiveContentInsetEnabled(true) .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() ) }
Ein sanftes Ein- oder Ausblenden anzeigen
Um deutlicher zu machen, dass ein Element in einer Kachel ein- oder ausgeblendet wird, oder um eine plötzliche Änderung des Werts einer Kachel subtiler darzustellen, können Sie in Ihren Kachel-Animationen Ein- und Ausblendungs- sowie Ein- und Ausgleiteffekte verwenden.
Wenn ein Kachel-Layout ein Element enthält, dessen Wert sich ändert, wird die Exit-Animation des Elements angezeigt. Anschließend wird das Layout aktualisiert und die Enter-Animation des Elements wird eingeblendet.
Ein- und Ausblendungen
Das folgende Code-Snippet zeigt, wie Ein- und Ausblendungen mit den Hilfsmethoden aus DefaultContentTransitions
durchgeführt werden. Um benutzerdefinierte FadeInTransition
- und FadeOutTransition
-Objekte zu definieren, rufen Sie setFadeIn()
bzw. setFadeOut()
in den Setter-Methoden für Übergänge auf.
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.fadeIn()) .setExitTransition(DefaultContentTransitions.fadeOut()) .build() ) .build() ) .build() ) ) .build() ) }
Folienübergänge
Das folgende Code-Snippet zeigt, wie Ein- und Ausblendungseffekte mit den Hilfsmethoden aus DefaultContentTransitions
ausgeführt werden. Sie können auch benutzerdefinierte SlideInTransition
- und SlideOutTransition
-Objekte definieren, indem Sie setSlideIn()
bzw. setSlideOut()
in den Setter-Methoden für Übergänge aufrufen.
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( ModifiersBuilders.SLIDE_DIRECTION_LEFT_TO_RIGHT ) ) .setExitTransition( DefaultContentTransitions.slideOut( ModifiersBuilders.SLIDE_DIRECTION_LEFT_TO_RIGHT ) ) .build() ) .build() ) .build() ) ) .build() ) }
Transformation anzeigen
Um die Aufmerksamkeit auf ein bestimmtes Element oder einen bestimmten Bereich in einer Kachel zu lenken, können Sie verschiedene Arten von Transformationen darauf anwenden, z. B. Drehung, Skalierung und Translation.
Viele Gleitkommawerte, die mit Transformationen verknüpft sind, akzeptieren dynamische Ausdrücke, mit denen Sie diese Transformationen animieren können.
Ausrichtung
Wenn Sie eine Drehung im Uhrzeigersinn um einen anpassbaren Drehpunkt ausführen möchten, verwenden Sie Code wie den folgenden:
return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, someTileText) .setModifiers( Modifiers.Builder() .setTransformation( 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(50f)) .setPivotY(dp(100f)) // Rotate the element 45 degrees clockwise. .setRotation(degrees(45f)) .build() ) .build() ) .build() ) ) .build() )
Skalierung
Wenn Sie ein Element mit horizontalen und vertikalen Skalierungsfaktoren vergrößern oder verkleinern möchten, verwenden Sie Code wie den folgenden:
return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, someTileText) .setModifiers( Modifiers.Builder() .setTransformation( 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(50f)) .setPivotY(dp(100f)) // Shrink the element by a scale factor // of 0.5 horizontally and 0.75 vertically. .setScaleX(FloatProp.Builder(0.5f).build()) .setScaleY(FloatProp.Builder(0.75f).build()) .build() ) .build() ) .build() ) ) .build() )
Geometrische Übersetzung
Wenn Sie ein Element um eine bestimmte Anzahl von geräteunabhängigen Pixeln (dp) horizontal oder vertikal über den Bildschirm bewegen möchten, verwenden Sie Code wie den folgenden:
return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, someTileText) .setModifiers( Modifiers.Builder() .setTransformation( ModifiersBuilders.Transformation.Builder() // Translate (move) the element 60 dp to the right // and 80 dp down. .setTranslationX(dp(60f)) .setTranslationY(dp(80f)) .build() ) .build() ) .build() ) ) .build() )
Lottie-Animationen
Kacheln unterstützen die Wiedergabe von Lottie-Animationen mit einer ähnlichen Syntax wie bei Bildern:
class LottieAnimation : TileService() { val lottieResourceId = "lottie_animation" override fun onTileRequest(requestParams: RequestBuilders.TileRequest): ListenableFuture<Tile> { val layout = LayoutElementBuilders.Image.Builder() .setWidth(dp(150f)) .setHeight(dp(150f)) .setResourceId(lottieResourceId) .build() return Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(Timeline.fromLayoutElement(layout)) .build() ) } override fun onTileResourcesRequest( requestParams: ResourcesRequest ): ListenableFuture<Resources> { val lottieImage = ResourceBuilders.ImageResource.Builder() .setAndroidLottieResourceByResId( ResourceBuilders.AndroidLottieResourceByResId.Builder(R.raw.lottie) .setStartTrigger(createOnVisibleTrigger()) .build() ) .build() return Futures.immediateFuture( Resources.Builder() .setVersion(requestParams.version) .addIdToImageMapping(lottieResourceId, lottieImage) .build() ) } }
Beachten Sie folgende Punkte:
- Es wird nur eine Teilmenge von Lottie-Dateien unterstützt. Prüfen Sie die Kompatibilität mit einem der folgenden Validatoren:
- Online-Validator: https://skottie.skia.org/ Im Bereich „Kompatibilitätsbericht“ muss die Datei die Tests „Spezifikationsfehler“, „Spezifikationswarnungen“ (mit ignorierten allgemeinen Eigenschaften) und „Fehler im Low-Power-Profil“ bestehen.
- Eine Rust-Validierungsbibliothek: https://github.com/google/lottie-tools.
- Die Lottie-Wiedergabe wird von Tile-Renderern mit einer Hauptversion von mindestens
1
und einer Nebenversion von mindestens500
unterstützt. Wenn eine bestimmte Animation nicht unterstützt wird, wird sie nicht angezeigt. Der Rest der Kachel wird jedoch wie erwartet gerendert. Bei Bedarf können Sie eine Fallback-Option wie ein statisches Bild angeben.
Wichtige Informationen nicht in der Mitte einer Animation anzeigen
Es gibt mehrere Situationen, in denen Animationen deaktiviert sind:
- Das Rendern von Kacheln durch das System kann Animationen für alle Kacheln deaktivieren.
- Eine Kachel kann jeweils nur vier Elemente 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. ihre Dauer, um wichtige Informationen anzuzeigen.