Bạn có thể tạo ảnh động cho thẻ thông tin của mình theo một vài cách, bao gồm các cách sau đây:
- Hiệu ứng quét khi chuyển tiếp sử dụng các ảnh động dạng tween.
- Hiệu ứng làm mờ từ từ và trượt các ảnh động vào và ra khỏi thẻ thông tin.
Hiện hiệu ứng quét khi chuyển tiếp
Để hiện hiệu ứng quét một cách mượt mà từ giá trị này sang giá trị khác, bạn có thể bật chế độ ảnh động dạng tween cho một phần tử, như trong đoạn mã sau đây:
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. ); }
Đặt hướng vòng cung
Nếu thẻ thông tin của bạn chứa hình cung, bạn có thể không muốn đường vòng cung hoặc văn bản luôn hiển thị
phát triển theo hướng văn bản mặc định cho ngôn ngữ mà người dùng chọn. Để chỉ định
hướng tăng trưởng vòng cung, hãy sử dụng các 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() ); }
Hiện hiệu ứng trượt hoặc làm mờ từ từ
Để cho thấy rõ hơn một phần tử đang xuất hiện hoặc biến mất trong một thẻ thông tin hoặc để chỉ ra theo một cách tinh tế hơn sự thay đổi lớn trong giá trị của thẻ thông tin, hãy sử dụng các hiệu ứng làm mờ và trượt trong ảnh động của thẻ.
Nếu bố cục của thẻ thông tin chứa một phần tử có giá trị thay đổi, thì thẻ thông tin sẽ hiện ảnh động thoát của phần tử, sau đó cập nhật bố cục và hiện ảnh động xuất hiện của phần tử.
Hiệu ứng chuyển đổi mờ dần
Đoạn mã sau đây minh hoạ cách thực hiện các hiệu ứng chuyển đổi mờ dần và rõ dần bằng các phương thức trợ giúp từ DefaultContentTransitions
. Để xác định đối tượng FadeInTransition
và FadeOutTransition
tuỳ chỉnh, hãy gọi setFadeIn()
và setFadeOut()
tương ứng trong các phương thức setter cho hiệu ứng chuyển đổi.
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() ); }
Hiệu ứng trượt khi chuyển tiếp
Đoạn mã khác sau đây minh hoạ cách thực hiện các hiệu ứng trượt ra và trượt vào khi chuyển tiếp bằng phương thức trợ giúp từ DefaultContentTransitions
. Bạn cũng có thể xác định đối tượng SlideInTransition
và SlideOutTransition
tuỳ chỉnh bằng cách gọi setSlideIn()
và setSlideOut()
tương ứng trong các phương thức setter cho hiệu ứng chuyển tiếp.
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() ); }
Hiển thị phép biến đổi
Để thu hút sự chú ý đến một phần tử hoặc vùng cụ thể trong thẻ thông tin, bạn có thể áp dụng nhiều các loại phép biến đổi, bao gồm: xoay, chia tỷ lệ và dịch thuật.
Nhiều giá trị dấu phẩy động liên kết với các phép biến đổi được chấp nhận biểu thức động, cho phép bạn tạo ảnh động cho các phép biến đổi này.
Góc xoay
Để xoay theo chiều kim đồng hồ quanh một điểm trung tâm có thể tuỳ chỉnh, hãy dùng mã tương tự như sau:
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() );
Điều chỉnh theo tỷ lệ
Để tăng hoặc thu nhỏ một phần tử theo hệ số tỷ lệ ngang và dọc, hãy sử dụng tương tự như sau:
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() );
Dịch hình học
Để di chuyển một phần tử theo một số pixel mật độ cụ thể (dp) trên màn hình theo chiều ngang hoặc chiều dọc, hãy sử dụng mã tương tự như sau:
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() );
Đừng hiển thị thông tin quan trọng ở giữa ảnh động
Có một số trường hợp trong đó ảnh động bị tắt:
- Quá trình kết xuất thẻ thông tin của hệ thống có thể tắt ảnh động cho tất cả các thẻ thông tin.
- Một thẻ thông tin chỉ có thể tạo ảnh động cho 4 phần tử cùng một lúc. Nếu bạn cố tạo ảnh động cho nhiều hơn 4 phần tử cùng lúc, thì không phải tất cả các phần tử đó đều hiện ảnh động.
Trong trường hợp ảnh động bị tắt, các phần tử sẽ ở dạng tĩnh và hiển thị giá trị kết thúc của ảnh động. Vì lý do này, đừng dựa vào hành vi của ảnh động, chẳng hạn như thời lượng, để hiển thị thông tin quan trọng.