시배's Android

TiTi Side Project | Animate Counter Timer 만들기 본문

Android/TiTi Side Project

TiTi Side Project | Animate Counter Timer 만들기

si8ae 2023. 9. 27. 22:50

TiTi 프로젝트에서는 Timer와 StopWatch 기능을 구현하기 위해, 실제 시간이 흐르는 듯한 Animate Counter Timer를 구현해야 합니다. 이 과정은 앱의 핵심 부분 중 하나이며, 사용자에게 시간 경과를 시각적으로 제공하는 중요한 요소입니다.

블로그 글에서는 Animate Counter Timer 구현 방법을 자세히 알아보겠습니다. 실제로 , , 초가 흐르는 것처럼 보이는 놀라운 효과를 어떻게 만들 있는지, 코드와 함께 상세히 살펴보겠습니다.

AnimatedCounter

@Composable
fun TdsAnimatedCounter(
    modifier: Modifier = Modifier,
    count: Int,
) {
    var oldCount by remember {
        mutableIntStateOf(count)
    }

    SideEffect {
        oldCount = count
    }

    Row(modifier = modifier) {
        val countString = count.toString().padStart(2, '0')
        val oldCountString = oldCount.toString().padStart(2, '0')
        for (i in countString.indices) {
            val oldChar = oldCountString.getOrNull(i)
            val newChar = countString[i]
            val char = if (oldChar == newChar) {
                oldCountString[i]
            } else {
                countString[i]
            }

            AnimatedContent(
                targetState = char,
                transitionSpec = {
                    slideInVertically { it } togetherWith slideOutVertically { -it }
                },
                label = ""
            ) { char ->
                Text(
                    text = char.toString(),
                )
            }
        }
    }
}
  • TdsAnimatedCounter는 Jetpack Compose를 사용하여 만든 Animate Counter Timer 컴포저블입니다.
  • count 파라미터로 현재 카운트 값을 전달 받습니다.
  • oldCount를 remember와 mutableIntStateOf를 사용하여 현재 카운트 값을 추적하는 변수로 선언합니다.
  • SideEffect 블록을 사용하여 oldCount 값을 현재 count 값으로 업데이트합니다. 이것은 애니메이션 효과를 위해 이전 카운트 값을 유지하는 데 사용됩니다.
  • Row 컴포저블을 사용하여 카운트를 가로로 나열합니다.
  • count와 oldCount를 두 자리 숫자 문자열로 변환하고, 각 자릿수를 비교하여 애니메이션을 적용합니다.
  • AnimatedContent를 사용하여 자릿수가 변경될 때 애니메이션 효과를 적용합니다. slideInVertically 및 slideOutVertically 트랜지션 스펙을 사용하여 위아래로 이동하는 효과를 적용합니다.
  • Text 컴포넌트를 사용하여 자릿수를 표시합니다.

TimeCounter

@Composable
fun TdsTimeCounter(
    modifier: Modifier = Modifier,
    hour: Int,
    minutes: Int,
    seconds: Int,
) {
    Row(modifier = modifier) {
        TdsAnimatedCounter(count = hour)
        Text(text = ":")
        TdsAnimatedCounter(count = minutes)
        Text(text = ":")
        TdsAnimatedCounter(count = seconds)
    }
}

00:00:00을 표시하기 위해 hour, minutes, seconds 파라미터로 시, 분, 초 값을 전달 받습니다. 시간 간격을 콜론(':')을 통해 표시합니다.

 

결과