[Android] 로딩 화면 만들기

uuranus·2024년 10월 8일
0
post-thumbnail

기존 애니메이션 분석

기존 로딩 애니메이션

시스템 아이콘인지 모르겠지만 요즘 이렇게 생긴 로딩화면을 많이 봐서 이 로딩화면을 만들어 볼 것이다.

기본 UI 그리기

저번에 star polygon을 그렸던 방식으로 degree를 이용해서 8개의 막대기를 돌아가면서 그려줄 것이다.

Canvas(
    modifier = modifier.fillMaxSize()
) {
    var currentRadian = 0.0

    val centerX = size.width / 2
    val centerY = size.height / 2

    val centerRadius = (size.minDimension) / 6f
    val radius = (size.minDimension / 2) - centerRadius
    val barWidth = centerRadius / 2

    repeat(numOfLoadingBar) { index ->
        val topLeftX = centerX + radius * sin(currentRadian).toFloat()
        val topLeftY = centerY - radius * cos(currentRadian).toFloat()

        val bottomLeftX = centerX + centerRadius * sin(currentRadian).toFloat()
        val bottomLeftY = centerY - centerRadius * cos(currentRadian).toFloat()

        val color = when {
            rotation == index -> Color.Gray
            (rotation + numOfLoadingBar - 1) % numOfLoadingBar == index -> Color.Gray.copy(alpha = 0.8f)
            (rotation + numOfLoadingBar - 2) % numOfLoadingBar == index -> Color.Gray.copy(alpha = 0.6f)
            (rotation + numOfLoadingBar - 3) % numOfLoadingBar == index -> Color.Gray.copy(alpha = 0.4f)
            else -> Color.Gray.copy(alpha = 0.2f)
        }

        drawLine(
            color = color,
            start = Offset(
                topLeftX,
                topLeftY
            ),
            end = Offset(
                bottomLeftX,
                bottomLeftY
            ),
            strokeWidth = barWidth,
            cap = StrokeCap.Round
        )

        currentRadian += radianDist
    }
}

회전시키기

val numOfLoadingBar = 8
val radianDist = 2 * PI / numOfLoadingBar

val infiniteRepeatable = rememberInfiniteTransition(label = "loading")

val rotation by infiniteRepeatable.animateValue(
    initialValue = 0,
    targetValue = numOfLoadingBar,
    typeConverter = Int.VectorConverter,
    animationSpec = infiniteRepeatable(
        animation = tween(durationMillis = 600, easing = LinearEasing)
    ),
    label = "loading"
)

현재 alpha값이 1인 막대기의 위치값을 infiniteRepeatable로 계속 반복하도록 하여서 계속 회전을 하는 것처럼 보여주었다.

최종 결과

깃허브 링크

https://github.com/uuranus/compose-animations

profile
Frontend Developer

0개의 댓글