Android [ Java, Kotlin ]

안드로이드 프로그래밍 - 커스텀 프로그래스바(Progressbar)

Moonsu99 2023. 10. 16. 11:20
  • OS - Mac OS 13.5.2
  • Tools - Android Studio Iguana | 2023.2.1 Canary 5
  • Language - Java
  • android version - 12
  • tartgetSDK - 33
  • minSDK - 28

요약

안드로이드 앱을 개발하다보면 프로그래스바를 사용하는 경우가 많다. 예를 들어 로딩화면을 구현하거나, 가입 과정 등 요긴하게 사용된다.

이번 포스트를 통해 프로그래스바를 커스텀 하는 방법을 제공하겠다.

 

해결방안

 

우선, xml파일을 따로 생성해서 include시키는 것이 코드의 재사용성에 이점이 있다.

custom_progressbar.xml파일을 하나 생성해서 관리한다.

 

progressbar은 다음과 같이 선언했다.

<ProgressBar
        android:layout_marginVertical="5dp"
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:progress="0"
        style="?android:attr/progressBarStyleHorizontal"
        android:progressDrawable="@drawable/custom_progressbar"
        android:max="100" />

style="?android:attr/progressBarStyleHorizontal" 를 사용했는데 이것은 기본 프로그래스 바가 원형으로 도는 것을 긴 Line 형식으로 변경해주는 코드다.

progressDrawble은 해당 프로그래스바에 대한 커스텀을 진행하는 파일이다.

 

custom_progressbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="2dp"/>
            <solid android:color="#F2F2F2"/>
        </shape>
    </item>
    <item android:id="@android:id/progress"
        android:top="1dp"
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <scale android:scaleWidth="100%">
            <shape>
                <corners android:radius="8dp"/>
                <gradient
                    android:startColor="#5A91F4"
                    android:endColor="#DA3DD4"
                    android:type="linear"
                    android:angle="0"/>
            </shape>
        </scale>
    </item>
</layer-list>

기본 색상은 #F2F2F2, gradient속성을 주어 프로그레스바의 증가하는 색상을 그라데이션으로 표현하게 작성했다.

 

그 다음. Kotlin파일에 프로그래스바에 대한 함수를 작성할 수 있다.

예를 들어 다음과 같은 함수를 작성하여 호출할 수 있다

private fun updateProgressBar(increment: Float = 0f) {
    // 현재 프로그레스를 가져옵니다.
    val currentProgress = progressBar.progress.toFloat()
    // 프로그레스를 increment만큼 증가시킵니다. 100 단위로 변경합니다.
    val newProgress = currentProgress + (increment * 100)
    // 최대값인 300을 넘지 않도록 합니다.
    val clampedProgress = newProgress.coerceAtMost(300F)

    // 부드러운 애니메이션을 적용하여 프로그래스 바를 업데이트합니다.
    progressBar.progress = clampedProgress.toInt()
}

해당 코드는 FrameLayout이 3개 존재할때 33%씩 증가시키며, 프로그래스바의 %가 증가할 때 부드럽게 증가하기 위해 작성한 함수이다. 

버튼 클릭 시 다음과 같이 함수를 호출할 수 있다

btn_next3.setOnClickListener {
    val frameUserApply2 = findViewById<FrameLayout>(R.id.frame_user_apply2)
    val frameUserApply3 = findViewById<FrameLayout>(R.id.frame_user_apply3)

    // activity_user_apply2를 gone으로 변경
    frameUserApply2.visibility = View.GONE

    // activity_user_apply3를 visible로 변경
    frameUserApply3.visibility = View.VISIBLE

    // ProgressBar를 100 단위로 증가시킵니다.
    val animator = ObjectAnimator.ofInt(progressBar, "progress", progressBar.progress, progressBar.progress + 100)
    animator.duration = 500
    animator.start()
}

비슷한 경우로 ScrollView를 끝까지 내렸을 때 프로그래스바의 %를 증가시킬 수 있다.

scrollView.viewTreeObserver.addOnScrollChangedListener {
    val scrollY = scrollView.scrollY
    val totalHeight = scrollView.getChildAt(0).height - scrollView.height

    // 스크롤이 마지막까지 내려갔을 때 (scrollY가 totalHeight와 같을 때) 나머지 1/3를 증가시킵니다.
    if (scrollY == totalHeight) {

        // ProgressBar를 100 단위로 증가.
        val animator = ObjectAnimator.ofInt(progressBar, "progress", progressBar.progress, progressBar.progress + 100)
        animator.duration = 500
        animator.start()
    }
}

 

 

여러가지 프로그래스바를 사용해서 커스텀 해보자.

https://developer.android.com/reference/android/widget/ProgressBar