안드로이드 시스템·Compose 용어 사전
ComposeAnimatedVisibility · animateContentSize · Transition

animate*AsState

목표 값을 선언하면 런타임이 그리로 부드럽게 이동시켜 주는 애니메이션 API.

목표 값을 선언하면 런타임이 그리로 부드럽게 이동시킨다.

val color by animateColorAsState(
    targetValue = if (isSelected) Blue else Gray,
    animationSpec = tween(300),
    label = "selection"
)
Box(Modifier.background(color))

명령형이라면

  • ValueAnimator 를 만들고 · 리스너를 붙이고 · 중간에 값이 바뀌면 취소하고 다시 시작

선언형이라면

  • "선택됐으면 파랑" 만 적는다
  • 중간에 값이 바뀌면 현재 위치에서 새 목표로 자연스럽게 이어진다 (인터럽트 처리가 공짜)

종류

animateFloatAsState · animateDpAsState · animateColorAsState
animateIntOffsetAsState · animateSizeAsState

// 나타남/사라짐
AnimatedVisibility(visible = expanded, enter = fadeIn() + expandVertically(),
                   exit = fadeOut() + shrinkVertically()) { Details() }

// 내용 교체
Crossfade(targetState = screen) { s -> when (s) { ... } }

// 크기 변화
Column(Modifier.animateContentSize()) { if (expanded) LongText() }

여러 값을 한 상태로 묶는다

val transition = updateTransition(targetState = isExpanded, label = "card")
val height by transition.animateDp(label = "h") { if (it) 200.dp else 80.dp }
val alpha by transition.animateFloat(label = "a") { if (it) 1f else 0.6f }
val corner by transition.animateDp(label = "c") { if (it) 0.dp else 16.dp }

개별 animateAsState 를 세 개 쓰면 각각 따로 돈다 (미세하게 어긋난다) Transition 은 하나의 상태 전환으로 묶어 조율한다

  • Android Studio 애니메이션 프리뷰에서도 함께 보인다 (label 이 그래서 필요하다)

spec 고르기

tween(300, easing = FastOutSlowInEasing) 시간 기반. 예측 가능하다

  • spring(dampingRatio = 0.6f) — 물리 기반. 제스처 뒤 이어질 때 자연스럽다
  • keyframes { } — 중간 지점을 지정한다 repeatable / infiniteRepeatable 반복

제스처로 시작한 움직임은 spring 이 낫다 — 속도를 이어받는다

무한 애니메이션

val infinite = rememberInfiniteTransition(label = "shimmer")
val x by infinite.animateFloat(
    0f, 1000f,
    infiniteRepeatable(tween(1200), RepeatMode.Restart), label = "x"
)

접근성

// 사용자가 '애니메이션 제거' 를 켰다면 존중한다
val reduce = LocalAccessibilityManager.current?.let { ... }

면접 함정

  • "애니메이션은 리컴포지션을 유발하지 않는다" → 값을 컴포지션에서 읽으면 프레임마다 돈다. graphicsLayer/offset {} 람다로 읽기를 늦춘다.
  • "AnimatedVisibility는 그냥 alpha 애니메이션" → 사라진 뒤 컴포지션에서도 제거된다. 상태가 함께 사라진다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — Compose 애니메이션 — animate*AsState·Transition