AnimatedVisibility와 전환
콘텐츠를 표시하고 숨기는 동작을 애니메이션 처리합니다.
AnimatedVisibility와 전환은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
나타나는 동작에 애니메이션 적용
콘텐츠가 갑자기 나타나거나 사라지면 어색하게 느껴집니다. Compose의 AnimatedVisibility는 컴포저블이 레이아웃에 들어오고 나갈 때 애니메이션을 적용합니다.
콘텐츠를 이 API로 감싸고 불리언 값으로 표시 여부를 제어하세요. 불리언 값이 변경되면 콘텐츠가 즉시 나타나는 대신 진입 또는 퇴장 애니메이션이 실행됩니다.
@Composable
fun Greeting(show: Boolean) {
AnimatedVisibility(visible = show) {
Text("Welcome aboard!")
}
}진입 및 퇴장 전환
enter 및 exit 매개변수를 사용하면 콘텐츠가 들어오고 나가는 방식을 정확하게 선택할 수 있습니다. 일반적인 구성 요소로는 fadeIn/fadeOut, slideIn/slideOut, expandVertically/shrinkVertically가 있습니다.
+ 연산자로 결합하면 여러 애니메이션을 동시에 실행할 수 있습니다.
@Composable
fun Toast(show: Boolean) {
AnimatedVisibility(
visible = show,
enter = fadeIn() + slideInVertically { it },
exit = fadeOut() + slideOutVertically { it }
) {
Text("Item added to cart")
}
}전환 사양 조정
각 진입/퇴장 전환은 animationSpec을 허용하므로 animate*AsState와 마찬가지로 지속 시간과 완화를 제어할 수 있습니다.
여기서는 콘텐츠가 300ms 동안 페이드 인되고 150ms 동안 더 빠르게 페이드 아웃됩니다. 이렇게 하면 닫히는 동작이 즉각적이고 경쾌하게 느껴집니다.
AnimatedVisibility(
visible = show,
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(150))
) {
Card { Text("Details") }
}확장 및 축소
더 많은 콘텐츠를 표시하는 섹션에서는 expandVertically와 shrinkVertically가 높이에 애니메이션을 적용해 주변 콘텐츠를 부드럽게 밀어냅니다.
접을 수 있는 패널, FAQ 항목 또는 "더 보기" 섹션에 적합합니다.
@Composable
fun Details(expanded: Boolean) {
AnimatedVisibility(
visible = expanded,
enter = expandVertically() + fadeIn(),
exit = shrinkVertically() + fadeOut()
) {
Text("Extra details revealed when expanded.")
}
}updateTransition: 하나의 상태, 여러 값
하나의 상태에 따라 여러 속성이 함께 변경되어야 할 때는 updateTransition이 이를 조정합니다. 이 API는 자식 요소들이 모두 동기화되어 애니메이션되는 Transition 객체를 생성합니다.
상태를 정의한 다음 각 속성에 대해 해당 상태를 기준으로 animateColor, animateDp 등을 사용하세요.
enum class BoxState { Collapsed, Expanded }
@Composable
fun MorphingBox(state: BoxState) {
val transition = updateTransition(state, label = "box")
val size by transition.animateDp(label = "size") {
if (it == BoxState.Expanded) 200.dp else 100.dp
}
val color by transition.animateColor(label = "color") {
if (it == BoxState.Expanded) Color.Magenta else Color.Cyan
}
Box(Modifier.size(size).background(color))
}전환에서 속성별 타이밍
updateTransition의 큰 장점은 속성별로 타이밍을 지정할 수 있다는 점입니다. 각 animate* 자식 요소는 자체 transitionSpec을 제공할 수 있으므로, 동일한 상태가 조정하는 동안에도 색상과 크기가 서로 다른 속도로 움직일 수 있습니다.
val size by transition.animateDp(
transitionSpec = { tween(durationMillis = 300) },
label = "size"
) { if (it == BoxState.Expanded) 200.dp else 100.dp }
val corner by transition.animateDp(
transitionSpec = { tween(durationMillis = 600) },
label = "corner"
) { if (it == BoxState.Expanded) 0.dp else 24.dp }AnimatedContent: 콘텐츠 교체
표시 여부만이 아니라 콘텐츠 자체가 변경될 때는 AnimatedContent를 사용하세요. 이 API는 이전 콘텐츠와 새 콘텐츠 사이에 애니메이션을 적용하며 기본적으로 교차 페이드합니다.
카운터, 단계 표시기 또는 로딩 상태와 로드 완료 상태 사이의 전환 등에 적합합니다.
@Composable
fun Counter(count: Int) {
AnimatedContent(
targetState = count,
label = "counter"
) { value ->
Text("$value", style = MaterialTheme.typography.headlineLarge)
}
}AnimatedContent 전환 사용자 지정
transitionSpec으로 AnimatedContent가 콘텐츠를 교체하는 방식을 사용자 지정할 수 있습니다. 카운터에서 흔히 사용하는 방식은 새 값이 위로 슬라이드되어 들어오고 이전 값이 슬라이드되어 나가도록 하면서 페이드를 함께 적용하는 것입니다.
using 키워드는 SizeTransform을 연결해 컨테이너 크기도 부드럽게 조정합니다.
AnimatedContent(
targetState = count,
transitionSpec = {
(slideInVertically { it } + fadeIn()) togetherWith
(slideOutVertically { -it } + fadeOut())
},
label = "counter"
) { value -> Text("$value") }목록 항목 애니메이션
LazyColumn 내부에서는 각 항목의 콘텐츠에 Modifier.animateItem()을 적용해 추가되거나 삭제되거나 이동되는 항목이 제자리로 들어오는 동작을 애니메이션으로 처리할 수 있습니다.
수동으로 항목을 추적하지 않아도 순서 변경과 삽입이 부드럽게 처리됩니다.
LazyColumn {
items(tasks, key = { it.id }) { task ->
Text(
task.title,
modifier = Modifier.animateItem()
)
}
}전체 화면에 크로스페이드 적용
Crossfade는 두 상태 사이를 페이드하는 간단하고 목적이 분명한 도우미로, 전체 화면이나 주요 UI 상태를 전환할 때 유용합니다.
현재 상태와 콘텐츠 람다를 전달하면 상태가 변경될 때 이전 콘텐츠는 페이드 아웃되고 새 콘텐츠는 페이드 인됩니다.
@Composable
fun ScreenHost(screen: Screen) {
Crossfade(targetState = screen, label = "screen") { current ->
when (current) {
Screen.Home -> HomeScreen()
Screen.Profile -> ProfileScreen()
}
}
}진입 자식 요소 조정
AnimatedVisibility 블록 내부에서는 AnimatedVisibilityScope를 사용할 수 있으며, 이 범위가 Modifier.animateEnterExit()를 제공합니다. 이를 사용하면 개별 자식 요소가 부모의 전환에 더해 자체 진입/퇴장 애니메이션을 실행할 수 있습니다.
예를 들어 패널이 슬라이드되어 들어오는 동안 제목은 약간 늦게 페이드 인되도록 하여 여러 층의 효과를 만들 수 있습니다.
AnimatedVisibility(visible = show, enter = slideInVertically()) {
Column {
Text(
"Title",
modifier = Modifier.animateEnterExit(
enter = fadeIn(tween(delayMillis = 100))
)
)
Text("Body")
}
}빠른 확인
숫자 3에서 숫자 4로 바뀔 때 새 값이 페이드 인되고 슬라이드되어 들어오도록 애니메이션하려고 합니다. 어떤 API가 가장 적합할까요?
복습: 표시 여부와 전환
이제 콘텐츠가 나타나고 사라지며 변경되는 동작에 애니메이션을 적용할 수 있습니다.
AnimatedVisibility는fadeIn/Out,slideIn/Out,expand/shrink를 사용해 진입/퇴장을 애니메이션으로 처리하며,+로 결합할 수 있습니다.updateTransition은 하나의 상태에서 파생된 여러 값을 조정하며, 각 값에 자체 사양을 지정할 수 있습니다.AnimatedContent는 서로 다른 콘텐츠 사이의 교체를 애니메이션으로 처리하고,Crossfade는 간단한 페이드 변형입니다.Modifier.animateItem()은 목록 항목의 삽입과 순서 변경을 애니메이션으로 처리합니다.
다음으로 제스처와 물리학 기반 스프링 애니메이션을 사용해 자연스럽고 상호작용적인 움직임을 만들어 봅니다.
자주 묻는 질문
“AnimatedVisibility와 전환” 강의는 무료인가요?
네 — “AnimatedVisibility와 전환” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“AnimatedVisibility와 전환”에서 뭘 배우나요?
콘텐츠를 표시하고 숨기는 동작을 애니메이션 처리합니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Android Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“AnimatedVisibility와 전환” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 애니메이션이 중요한 이유
- animate*AsState 기초
- AnimatedVisibility와 전환
- 제스처와 스프링 애니메이션