[Kotlin / Compose] Animation

Subeen·2024년 4월 23일
1

Compose

목록 보기
9/20

Animation

Jetpack Compose에서 AnimationUI 요소의 변화를 시각적으로 부드럽게 표현하고 상호작용성을 향상시키는 데 사용된다.

/*
 * 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 = "흰색")
        }
    }
}

animateColorAsStateanimateFloatAsState 함수는 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()과 같은 애니메이션 효과를 지정할 수 있다.

updateTransition

animateColorAsStateanimateFloatAsState를 사용하면 각각의 애니메이션 상태가 독립적으로 관리되어 상태의 일관성을 유지하기 어려울 수 있다. 여러 애니메이션 상태를 일관되게 조절하거나 연결하는 데 어려움이 있을 수 있기에 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.animateColortransition.animateFloat는 Jetpack Compose에서 updateTransition을 사용하여 애니메이션을 정의할 때 특정 속성의 애니메이션을 제어하기 위한 함수이다.
transition.animateColor : 색상 속성에 대한 애니메이션을 정의하는 데 사용되며 배경색이나 텍스트 색상과 같은 색상 속성을 애니메이션화할 때 사용된다.
transition.animateFloat : 부동 속성에 대한 애니메이션을 정의하는 데 사용되며 투명도와 같은 부동 속성을 애니메이션화할 때 사용된다.

profile
개발 공부 기록 🌱

0개의 댓글