功能块支持几种不同的动画方法,包括:
- 使用补间动画的清除过渡效果。
- 平滑的淡出淡入和滑动动画效果(适用于进入和退出功能块)。
- Lottie 动画。
显示清除过渡效果
若要显示两个值之间的平滑清除效果,您可以为元素启用补间动画,如以下代码段所示:
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() ) }
设置弧形方向
如果您的图块包含弧线,您可能不希望弧线或文字始终按照用户所选语言的默认文字方向增长。如需指定弧的增长方向,请使用 ArcDirection
API:
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() ) }
显示平滑的淡出淡入或滑动效果
为了更清楚地指明元素在功能块中出现或消失的动作,或者更精细地显示在功能块中分步变化的值,请在功能块动画中使用淡入淡出和滑动效果。
如果功能块布局包含值会发生变化的元素,功能块会显示该元素的退出动画,然后更新布局并显示该元素的进入动画。
淡出淡入过渡
以下代码段演示了如何使用 DefaultContentTransitions
中的辅助方法执行淡入和淡出过渡。如需定义自定义的 FadeInTransition
和 FadeOutTransition
对象,请在过渡 setter 方法中分别调用 setFadeIn()
和 setFadeOut()
。
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() ) }
滑动过渡
另一个代码段演示了如何使用 DefaultContentTransitions
中的辅助方法执行滑入和滑出过渡。您还可以通过在过渡 setter 方法中分别调用 setSlideIn()
和 setSlideOut()
来定义自定义的 SlideInTransition
和 SlideOutTransition
对象。
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() ) }
显示转换
如需突出显示图块中的特定元素或区域,您可以对其应用多种类型的转换,包括旋转、缩放和平移。
与转换关联的许多浮点值都接受动态表达式,可让您为这些转换添加动画效果。
旋转
如需围绕可自定义的旋转中心点执行顺时针旋转,请使用类似以下的代码:
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() )
扩缩
如需按横向和纵向缩放比例放大或缩小元素,请使用类似于以下内容的代码:
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() )
几何平移
如需在屏幕上水平或垂直移动元素,使其移动特定数量的密度像素 (dp),请使用类似以下代码的代码:
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 动画
功能块支持播放 Lottie 动画,使用的语法与图片类似:
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() ) } }
请注意以下几点:
- 仅支持部分 Lottie 文件。使用以下验证器之一检查兼容性:
- 在线验证器:https://skottie.skia.org/。在“兼容性报告”部分,文件需要通过“规范错误”“规范警告”(忽略通用属性)和“低功耗配置文件错误”测试。
- 一个 Rust 验证库:https://github.com/google/lottie-tools。
- 主要版本至少为
1
且次要版本至少为500
的 tile 渲染器支持 Lottie 播放。如果不支持给定的动画,则不会显示该动画,但图块的其余部分会按预期呈现。如有需要,您可以提供后备选项,例如静态图片。
不要在动画播放过程中显示重要信息
以下列举几种会停用动画的情况:
- 系统的功能块渲染程序可能会停用所有功能块的动画。
- 一个功能块一次只能为 4 个元素添加动画效果。如果您尝试同时为超过 4 个元素添加动画效果,其中有些元素会无法显示动画。
如果动画已停用,相应元素就会处于静态,并显示动画的结束值。因此,请勿依赖动画的行为(例如持续时间)来显示重要信息。