이제 몇 가지 기본 애니메이션 API에 익숙해졌으므로 더 복잡한 애니메이션을 만들 수 있는 Transition API를 살펴보자. 이 예에서는 탭 인디케이터를 커스터마이징 한다. 이는 현재 선택된 탭에 표시되는 사각형이다.
HomeTabIndicator 컴포저블에서 TODO 4를 찾아 탭 인디케이터가 어떻게 구현되는지 확인해보자.
val indicatorLeft = tabPositions[tabPage.ordinal].left
val indicatorRight = tabPositions[tabPage.ordinal].right
val color = if (tabPage == TabPage.Home) Purple700 else Green800
여기서 IndicatorLeft는 탭 행(tab row)에서 인디케이터의 왼쪽 테두리고, IndicatorRight는 인디케이터의 오른쪽 테두리다. 색상도 보라색과 녹색 사이에서 변경된다.
이러한 여러 값을 동시에 애니메이션하기 위해 Transition을 사용할 수 있다. updateTransition 함수로 트랜지션을 생성할 수 있다. targetState 매개변수로 현재 선택된 탭의 인덱스를 전달한다.
각 애니메이션 값은 Transition의 animate* 확장 함수로 선언될 수 있다. 이 예제에서는 animateDp 및 animateColor를 사용한다. 그것들은 람다 블록을 사용하고, 우리는 각 상태에 대한 목표 값을 지정할 수 있다. 목표 값이 무엇인지 이미 알고 있으므로 아래와 같이 값을 간단히 래핑할 수 있다. animate* 함수가 State 객체를 반환하기 때문에 여기에서 by 선언을 사용하고, 이를 다시 local delegated property 만들 수 있다.
val transition = updateTransition(tabPage)
val indicatorLeft by transition.animateDp { page ->
tabPositions[page.ordinal].left
}
val indicatorRight by transition.animateDp { page ->
tabPositions[page.ordinal].right
}
val color by transition.animateColor { page ->
if (page == TabPage.Home) Purple700 else Green800
}
지금 앱을 실행하면 훨씬 더 흥미롭다는 탭 전환이 되는 것을 알 수 있다. 탭을 클릭해 tabPage 상태 값이 변경됨에 따라, 전환과 관련된 모든 애니메이션 값이 대상 상태에 대해 지정된 값으로 애니메이션 되기 시작한다.
또한, transitionSpec 매개변수를 지정하여 애니메이션 동작을 커스터마이징 할 수 있다. 예를 들어, 목적지에 더 가까운 가장자리가 다른 가장자리보다 빠르게 움직이도록 함으로써 인디케이터에 대한 탄성 효과를 얻을 수 있다. transitionSpec 람다에서 isTransitioningTo infix 함수를 사용하여 상태 변경 방향을 결정할 수 있다.
val transition = updateTransition(
tabPage,
label = "Tab indicator"
)
val indicatorLeft by transition.animateDp(
transitionSpec = {
if (TabPage.Home isTransitioningTo TabPage.Work) {
// 인디케이터가 오른쪽으로 이동한다.
// 왼쪽 엣지가 오른쪽 엣지보다 천천히 이동한다.
spring(stiffness = Spring.StiffnessVeryLow)
} else {
// 인디케이터가 왼쪽으로 이동한다.
// 왼쪽 엣지가 오른쪽 엣지보다 빠르게 이동한다.
spring(stiffness = Spring.StiffnessMedium)
}
},
label = "Indicator left"
) { page ->
tabPositions[page.ordinal].left
}
val indicatorRight by transition.animateDp(
transitionSpec = {
if (TabPage.Home isTransitioningTo TabPage.Work) {
// 인디케이터가 오른쪽으로 이동한다.
// 오른쪽 엣지가 왼쪽 엣지보다 빠르게 이동한다.
spring(stiffness = Spring.StiffnessMedium)
} else {
// 인디케이터가 왼쪽으로 이동한다.
// 오른쪽 엣지가 왼쪽 엣지보다 느리게 이동한다.
spring(stiffness = Spring.StiffnessVeryLow)
}
},
label = "Indicator right"
) { page ->
tabPositions[page.ordinal].right
}
val color by transition.animateColor(
label = "Border color"
) { page ->
if (page == TabPage.Home) Purple700 else Green800
}
앱을 다시 실행하고 탭을 전환해 보자.
Android Studio는 컴포즈 Preview에서 전환 검사를 지원한다. 애니메이션 미리보기를 사용하려면, 미리보기에서 컴포저블의 오른쪽 상단 모서리에 있는 “Start interactive mode” 아이콘을 클릭하여 인터렉티브 모드를 시작한다. 아이콘을 찾을 수 없는 경우 여기에 설명된 대로 실험실 설정에서 이 기능을 활성화해야 한다. PreviewHomeTabBar 컴포저블 아이콘을 클릭해 보자. 그런 다음 인터렉티브 모드의 오른쪽 상단 모서리에 있는 “Start animation inspection” 아이콘을 클릭한다. 그러면 새 “Animations” 창이 열린다.
“Play” 아이콘 버튼을 클릭하여 애니메이션을 실행할 수 있다. seekbar를 드래그해 각 애니메이션 프레임을 볼 수도 있다. 애니메이션 값에 대한 더 나은 설명을 위해 updateTransition 및 animate* 메서드에서 label 매개변수를 지정할 수 있다.
0개의 댓글