Jetpack Compose에서 Animation은 UI 요소의 변화를 시각적으로 부드럽게 표현하고 상호작용성을 향상시키는 데 사용된다.
/*
* RadioButton을 클릭하여 "Hello World" 텍스트를 보이게 하거나 숨길 수 있으며
* 배경색을 빨간색 또는 흰색으로 선택할 수 있다.
*/
@Composable
fun AnimationEx() {
/*
* 텍스트의 가시성을 제어
* remember { mutableStateOf() }를 사용하여 상태를 저장하고 관리한다.
*/
var helloWorldVisible by remember {
mutableStateOf(true)
}
/* 배경색을 제어
* remember { mutableStateOf() }를 사용하여 상태를 저장하고 관리한다.
*/
var isRed by remember {
mutableStateOf(false)
}
// val backgroundColor = Color.LightGray
/*
* 배경색을 제어
* animateColorAsState 함수를 사용하여 배경색에 애니메이션 효과를 부여한다.
*/
val backgroundColor by animateColorAsState(
targetValue = if (isRed) Color.Red else Color.White, label = "backgroundColor"
)
/*
* 투명도를 제어
* animateFloatAsState 함수를 사용하여 투명도에 애니메이션 효과를 부여한다.
*/
val alpha by animateFloatAsState(
targetValue = if (isRed) 1.0f else 0.5f, label = "alpha"
)
Column(
modifier = Modifier
.padding(16.dp)
.background(backgroundColor)
.alpha(alpha)
) {
AnimatedVisibility(
visible = helloWorldVisible,
// enter = expandIn()
// enter = expandHorizontally()
// enter = expandVertically
// enter = slideIn()
// enter = slideInVertically()
// enter = fadeIn()
enter = slideInVertically() + expandHorizontally(),
exit = slideOutHorizontally()
) {
Text(text = "Hello World!")
}
Row(
modifier = Modifier.selectable(
selected = helloWorldVisible,
onClick = {
helloWorldVisible = true
}
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = helloWorldVisible,
onClick = { helloWorldVisible = true }
)
Text(text = "Hello World 보이기")
}
Row(
modifier = Modifier.selectable(
selected = !helloWorldVisible,
onClick = {
helloWorldVisible = false
}
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = !helloWorldVisible,
onClick = { helloWorldVisible = false }
)
Text(text = "Hello World 감추기")
}
Text(text = "배경색을 바꿔봅시다.")
Row(
modifier = Modifier.selectable(
selected = isRed,
onClick = {
isRed = true
}
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = isRed,
onClick = { isRed = true }
)
Text(text = "빨간색")
}
Row(
modifier = Modifier.selectable(
selected = !isRed,
onClick = {
isRed = false
}
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = !isRed,
onClick = { isRed = false }
)
Text(text = "흰색")
}
}
}
animateColorAsState 및 animateFloatAsState 함수는 Jetpack Compose에서 사용되는 애니메이션 효과를 제공하는 함수이다.
- animateColorAsState : 색상 값의 애니메이션을 정의하고 적용하는 데 사용된다.
- targetValue : 애니메이션의 목표 색상 값을 나타낸다.
- animationSpec : 애니메이션의 속도 및 곡선 등을 정의하는데 사용되며,
tween, spring, keyframes
와 같은 애니메이션 스펙을 사용할 수 있다.- finishedListener : 애니메이션이 완료되었을 때 실행되는 콜백이다.
- animateFloatAsState : 부동 소수점 값의 애니메이션을 정의하고 적용하는 데 사용된다.
- targetValue : 애니메이션의 목표 값으로, 부동 소수점 형식이다.
- animationSpec : 애니메이션의 속도 및 곡선을 정의하는데 사용되며,
tween, spring, keyframes
와 같은 애니메이션 스펙을 사용할 수 있다.- finishedListener : 애니메이션이 완료되었을 때 실행되는 콜백이다.
AnimatedVisibility는 Jetpack Compose에서 사용되는 컴포저블 중 하나로, UI 요소의 가시성을 변경할 때 애니메이션을 적용하는 데 사용된다. 이를 통해 요소가 나타나거나 사라질 때 부드러운 애니메이션 효과를 적용할 수 있다.
- 주요 속성
- visible : UI 요소의 가시성을 제어하는 Boolean 값이다. 이 값이 true이면 UI 요소가 보이고, false이면 UI 요소가 숨겨진다.
- enter : UI 요소가 나타날 때 적용할 애니메이션을 정의하는데 사용된다. 예를 들어, fadeIn()이나 slideIn()과 같은 애니메이션 효과를 지정할 수 있다.
- exit : UI 요소가 사라질 때 적용할 애니메이션을 정의하는데 사용된다. 예를 들어, fadeOut()나 slideOut()과 같은 애니메이션 효과를 지정할 수 있다.
animateColorAsState 및 animateFloatAsState를 사용하면 각각의 애니메이션 상태가 독립적으로 관리되어 상태의 일관성을 유지하기 어려울 수 있다. 여러 애니메이션 상태를 일관되게 조절하거나 연결하는 데 어려움이 있을 수 있기에 transition을 사용하여 여러 애니메이션 상태를 한꺼번에 관리하고 조절할 수 있다.
@Composable
fun RadioButtonWithText(
text: String,
color: Color = Color.Black,
selected: Boolean,
onClick: () -> Unit
) {
Row(
modifier = Modifier.selectable(
selected = selected,
onClick = onClick
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(selected = selected, onClick = onClick)
Text(text = text, color = color)
}
}
@Composable
fun Animation2Ex() {
var isDarkMode by remember { mutableStateOf(false) }
// animateColorAsState(targetValue = )
// animateFloatAsState(targetValue = )
val transition = updateTransition(targetState = isDarkMode, label = "Dark Mode Transition")
val backgroundColor by transition.animateColor(label = "Dark Mode Background Animation") { state ->
when (state) {
false -> Color.White
true -> Color.Black
}
}
val color by transition.animateColor(
label = "Dark Mode Text Color Animation"){ state ->
when (state) {
false -> Color.Black
true -> Color.White
}
}
val alpha by transition.animateFloat(
label = "Dark Mode Alpha Animation") {state ->
when (state) {
false -> 0.7f
true -> 1.0f
}
}
Column (
modifier = Modifier.background(backgroundColor)
.alpha(alpha)
){
RadioButtonWithText(text = "일반 모드", color = color, selected = !isDarkMode) {
isDarkMode = false
}
RadioButtonWithText(text = "다크 모드", color = color, selected = isDarkMode) {
isDarkMode = true
}
Row {
Box(
modifier = Modifier
.background(Color.Red)
.size(20.dp)
) {
Text(text = "1")
}
Box(
modifier = Modifier
.background(Color.Magenta)
.size(20.dp)
) {
Text(text = "2")
}
Box(
modifier = Modifier
.background(Color.Blue)
.size(20.dp)
) {
Text(text = "3")
}
}
}
}
updateTransition은 Jetpack Compose에서 상태 변화를 기반으로 애니메이션을 제어하기 위한 함수로 현재 상태와 대상 상태를 빅하여 애니메이션을 자동으로 계산하고 적용한다.
- targetState : 애니메이션의 목표 상태를 나타내는 변수로 이 변수의 변화에 따라 애니메이션이 트리거된다.
- label : 선택적 매개변수로 트랜지션을 식별하는 데 사용된다. 이 값을 설정하면 디버깅 및 로깅에서 트랜지션을 식별할 때 도움이 된다.
transition.animateColor 및 transition.animateFloat는 Jetpack Compose에서 updateTransition을 사용하여 애니메이션을 정의할 때 특정 속성의 애니메이션을 제어하기 위한 함수이다.
transition.animateColor : 색상 속성에 대한 애니메이션을 정의하는 데 사용되며 배경색이나 텍스트 색상과 같은 색상 속성을 애니메이션화할 때 사용된다.
transition.animateFloat : 부동 속성에 대한 애니메이션을 정의하는 데 사용되며 투명도와 같은 부동 속성을 애니메이션화할 때 사용된다.