visible:Boolean값에 따라 content를 애니메이션 처리하는 컴포저블이다
애니메이션이 끝난 후에는 content가 트리에서 제거되기때문에 상태 변화를 관찰하거나 추가 작업(ex. 데이터 삭제, 순차적 애니메이션 등)을 수행하려면 mutableTransitionState를 사용하는 AnimatedVisibility를 사용하도록 하자
기본적인 enter 동작은 fadeIn+expandIn(서서히 나타나면서 커지는)조합이며, exit 또한 그 반대로 생각하면 된다.
4가지의 유형(fade, Expand/Shrink, Sacle, Slide)의 EnterTransition과 ExitTransition을 지원하며, +를 사용해 결합하여 사용한다(애니메이션 동시진행 -> 결합 순서 상관x) (하단 예시1 코드 참고)
AnimatedVisibility는 enter/exit 애니메이션이 모두 완료될 때까지 애니메이션의 상태를 관리하고 대기한다
content에 맞는 레이아웃을 생성하며 모든 자식들은 레이아웃의 상단 시작부분에 정렬된다
RowScope(or ColumnScope).AnimatedVisible 로 정의되어 있기 때문에, Row/Column에 배치되면 해당 컨테이너에 맞게 enter/exit가 조정된다
커스텀 애니메이션도 정의할 수 있다 AnimatedVisibilityScope의 Transition<EnterExitState>객체를 사용(scope안에서 transition.animatexxx를 사용하면 된다.)(하단 예시2 코드 참고)
커스텀된 애니메이션은 enter및 exit에서 지정된 내장 애니메이션과 함께 실행되기에 모든 애니메이션을 커스텀하고 싶다면 enter/exit을 EnterTransition.None으로 설정해서 만들면 된다.
예시1)
AnimatedVisibility(
visible = visible,
enter =
// 수직으로 슬라이드하며 나타남
// 초기y가 -40으로 지정하여 위에서 아래로 슬라이드
slideInVertically(initialOffsetY = { -40 })
// 정렬 기준(Top)에서부터 수직으로 확장되며 나타남
+ expandVertically(expandFrom = Alignment. Top)
// 크기가 커지면서 나타남
+ scaleIn(transformOrigin = TransformOrigin(0.5f, 0f))
// 서서히 보이게 나타남
+ fadeIn(initialAlpha = 0.3f),
exit = slideOutVertically() + shrinkVertically()
+ fadeOut() + scaleOut(targetScale = 1.2f)
)
예시2)
AnimatedVisibility(
...
) {
// transition = Transition<EnterExitState>
val cornerRadius by transition.animateDp {
when (it) {
// 애니메이션이 아직 실행되지 않은 초기 상태
EnterExitState.PreEnter -> 0.dp
// content가 화면에 등장
EnterExitState.Visible -> 50.dp
// content가 화면에서 사라질 경우
EnterExitState.PostExit -> 50.dp}
}
Box(Modifier
.background(
Color.Red,
shape = RoundedCornerShape(cornerRadius))
.height(100.dp).fillMaxWidth())
}