다음을 비롯한 몇 가지 방법으로 카드에 애니메이션을 적용할 수 있습니다.
- 트윈 애니메이션을 사용하여 스윕 전환.
- 카드 안으로 또는 바깥으로 애니메이션의 부드러운 페이드 및 슬라이드.
스윕 전환 표시
한 값에서 다른 값으로 부드러운 스윕을 표시하려면 다음 코드 스니펫과 같이 요소에 트윈 애니메이션을 적용하면 됩니다.
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. )
자바
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. ); }
호 방향 설정
카드에 원호가 있는 경우 원호 선이나 텍스트가 항상
사용자가 선택한 언어의 기본 텍스트 방향으로 늘어남 지정
호의 성장 방향이 필요하다면 ArcDirection
API를 사용하세요.
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() ); }
부드러운 페이드 또는 슬라이드 표시
카드에서 요소가 나타나거나 사라지는 것을 더 명확하게 나타내거나 카드 값의 단계 변화를 더 정교하게 표시하려면 카드 애니메이션에 페이드 및 슬라이드 효과를 사용합니다.
카드 레이아웃에 값이 변경되는 요소가 포함된 경우, 요소의 종료 애니메이션이 표시된 다음 레이아웃이 업데이트되고 요소의 진입 애니메이션이 표시됩니다.
페이드 전환
다음 코드 스니펫은 DefaultContentTransitions
의 도우미 메서드를 사용하여 페이드 인 및 페이드 아웃 전환을 실행하는 방법을 보여줍니다. 맞춤 FadeInTransition
및 FadeOutTransition
객체를 정의하려면 전환 setter 메서드에서 각각 setFadeIn()
및 setFadeOut()
을 호출합니다.
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() ); }
슬라이드 전환
다음 코드 스니펫은 DefaultContentTransitions
의 도우미 메서드를 사용하여 슬라이드 인 및 슬라이드 아웃 전환을 실행하는 방법을 보여줍니다. 전환 setter 메서드에서 setSlideIn()
및 setSlideOut()
을 호출하여 맞춤 SlideInTransition
및 SlideOutTransition
객체를 정의할 수도 있습니다.
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() ) }
자바
@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() ); }
변환 표시
카드의 특정 요소나 영역에 주의를 환기하려면 회전, 확장, 변환 등 여러 유형의 변환을 포함합니다.
변환과 관련된 많은 부동 소수점 값은 동적 표현식을 사용하여 이러한 변환에 애니메이션을 적용할 수 있습니다.
회전
맞춤설정 가능한 피벗 포인트를 중심으로 시계 방향으로 회전하려면 다음과 비슷합니다.
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() )
자바
// 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() );
크기 조정
가로 및 세로 배율로 요소를 늘리거나 줄이려면 다음을 사용합니다. 코드를 다음과 같이 작성할 수 있습니다.
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() )
자바
// 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() );
기하학적 변환
화면에서 요소를 특정 수의 밀도 픽셀 (dp)만큼 이동 가로 또는 세로로 다음과 유사한 코드를 사용합니다.
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() );
애니메이션 중간에 중요한 정보를 표시하지 말 것
애니메이션이 사용 중지되는 몇 가지 상황이 있습니다.
- 시스템의 카드 렌더링으로 인해 모든 카드의 애니메이션이 사용 중지될 수 있는 경우.
- 카드는 한 번에 4개의 요소에만 애니메이션을 적용할 수 있으며, 한 번에 5개 이상의 요소에 애니메이션을 적용하려고 하면 일부 요소에는 애니메이션이 표시되지 않음.
애니메이션이 사용 중지된 경우 요소에 애니메이션의 종료 값만 정적으로 표시됩니다. 따라서 중요한 정보를 표시할 때는 애니메이션의 길이와 같은 동작에 의존해서는 안 됩니다.