공유 요소 전환 애니메이션이 실행되는 방식을 맞춤설정하기 위해 공유 요소가 전환되는 방식을 변경하는 데 사용할 수 있는 몇 가지 매개변수가 있습니다.
애니메이션 사양
크기 및 위치 이동에 사용되는 애니메이션 사양을 변경하려면 Modifier.sharedElement()
에서 다른 boundsTransform
매개변수를 지정하면 됩니다.
이렇게 하면 초기 Rect
위치와 타겟 Rect
위치가 제공됩니다.
예를 들어 앞의 예시에서 텍스트가 호 모양으로 움직이도록 하려면 keyframes
사양을 사용하도록 boundsTransform
매개변수를 지정합니다.
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
AnimationSpec
는 아무거나 사용해도 됩니다. 이 예시에서는 keyframes
사양을 사용합니다.
boundsTransform
매개변수를 보여주는 예크기 조절 모드
공유된 두 경계 사이에서 애니메이션을 적용할 때 resizeMode
매개변수를 RemeasureToBounds
또는 ScaleToBounds
로 설정할 수 있습니다. 이 매개변수는 두 상태 간에 공유 요소가 전환되는 방식을 결정합니다. ScaleToBounds
은 먼저 lookahead (또는 타겟) 제약 조건으로 하위 레이아웃을 측정합니다. 그런 다음 하위 요소의 안정적인 레이아웃이 공유 경계에 맞게 조정됩니다.
ScaleToBounds
는 상태 간의 '그래픽 스케일'로 생각할 수 있습니다.
반면 RemeasureToBounds
는 타겟 크기를 기반으로 애니메이션 처리된 고정 제약 조건으로 sharedBounds
의 하위 레이아웃을 다시 측정하고 다시 레이아웃합니다. 다시 측정은 경계 크기 변경에 의해 트리거되며, 이는 프레임마다 발생할 수 있습니다.
Text
컴포저블의 경우 ScaleToBounds
을 사용하면 텍스트가 다른 줄로 재배치되고 다시 흐르는 것을 방지할 수 있으므로 ScaleToBounds
이 권장됩니다. RemeasureToBounds
는 가로세로 비율이 다른 경계에 권장되며, 두 공유 요소 간에 부드러운 연속성을 원하는 경우에도 권장됩니다.
두 크기 조절 모드의 차이점은 다음 예에서 확인할 수 있습니다.
|
|
---|---|
최종 레이아웃으로 건너뛰기
기본적으로 두 레이아웃 간에 전환할 때 레이아웃 크기는 시작 상태와 최종 상태 사이에서 애니메이션 처리됩니다. 텍스트와 같은 콘텐츠를 애니메이션으로 처리할 때는 이 동작이 바람직하지 않을 수 있습니다.
다음 예에서는 'Lorem Ipsum' 설명 텍스트가 두 가지 다른 방식으로 화면에 표시됩니다. 첫 번째 예에서는 컨테이너의 크기가 커지면서 텍스트가 리플로우됩니다. 두 번째 예에서는 텍스트가 커져도 리플로우되지 않습니다. Modifier.skipToLookaheadSize()
를 추가하면 증가할 때 리플로우가 방지됩니다.
|
|
---|---|
클립 및 오버레이
공유 요소가 서로 다른 컴포저블 간에 공유되려면 전환이 대상의 일치 항목으로 시작될 때 컴포저블의 렌더링이 레이어 오버레이로 상승됩니다. 이렇게 하면 상위 요소의 경계와 레이어 변환 (예: 알파 및 크기 조절)이 이스케이프됩니다.
공유되지 않은 다른 UI 요소 위에 렌더링됩니다. 전환이 완료되면 요소가 오버레이에서 자체 DrawScope
로 드롭됩니다.
공유 요소를 도형에 클리핑하려면 표준 Modifier.clip()
함수를 사용합니다. sharedElement()
뒤에 배치합니다.
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
공유된 요소가 상위 컨테이너 외부에서 렌더링되지 않도록 하려면 sharedElement()
에서 clipInOverlayDuringTransition
를 설정하면 됩니다. 기본적으로 중첩된 공유 경계의 경우 clipInOverlayDuringTransition
는 상위 sharedBounds()
의 클립 경로를 사용합니다.
공유 요소 전환 중에 하단 탐색 메뉴나 플로팅 작업 버튼과 같은 특정 UI 요소를 항상 상단에 유지하려면 Modifier.renderInSharedTransitionScopeOverlay()
를 사용하세요. 기본적으로 이 수정자는 공유 전환이 활성 상태인 동안 오버레이에 콘텐츠를 유지합니다.
예를 들어 Jetsnack에서는 화면이 표시되지 않을 때까지 BottomAppBar
를 공유 요소 위에 배치해야 합니다. 컴포저블에 수정자를 추가하면 컴포저블이 계속 올라갑니다.
|
다음으로 서명됨: |
---|---|
전환 전에 공유되지 않은 컴포저블이 애니메이션으로 사라지고 다른 컴포저블 위에 유지되기를 원할 수 있습니다. 이러한 경우 renderInSharedTransitionScopeOverlay().animateEnterExit()
를 사용하여 공유 요소 전환이 실행될 때 컴포저블이 사라지도록 애니메이션을 적용합니다.
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
공유 요소가 오버레이로 렌더링되지 않도록 하려면 sharedElement()
에서 renderInOverlayDuringTransition
을 false로 설정하면 됩니다.
공유 요소 크기 변경사항을 형제 레이아웃에 알림
기본적으로 sharedBounds()
및 sharedElement()
는 레이아웃이 전환될 때 크기 변경을 상위 컨테이너에 알리지 않습니다.
전환 시 크기 변경사항을 상위 컨테이너에 전파하려면 placeHolderSize
매개변수를 PlaceHolderSize.animatedSize
로 변경하세요. 이렇게 하면 항목이 커지거나 작아집니다. 레이아웃의 다른 모든 항목은 변경에 응답합니다.
|
(한 항목이 커지면 목록의 다른 항목이 아래로 이동하는 것을 확인하세요.) |
---|---|