[Android] Progress 를 나타내는 Custom ProgressBar 구현하기

2021. 8. 8. 21:48Android

반응형

최근에 회사에서 custom progress bar 를 개발해야 했었다. 여기서 custom progress bar 는, spinning 하지 않는 고정된 progress 값을 표현하는 progress bar 이다. 즉, 평소에 네트워크 로딩 등에 사용되는 무한 로딩이 도는 progress bar 와 달리, spinning 하지 않는 아이를 만들어야 했다.

 

 

결과물

아래는 결과물이다.

Progress를 나타내는 custom ProgressBar

 

이때 조건은 아래와 같다. 

  • progress max 값 : 100
  • progressBar width : 76dp. 즉 바깥 원(outer circle)의 지름이 76dp
  • progressBar 두께 : 10dp
  • 내부 원(inner circle) 지름 : 56dp 

 

 

실제 구현 - ProgressBar

위의 결과물을 만들기 위해서 나는 우리가 평소에 애용하는 ProgressBar 를 사용했다. 

아래는 사용한 ProgressBar 코드이다.

    <ProgressBar
        android:id="@+id/progressbar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="76dp"
        android:layout_height="76dp"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        android:indeterminate="false"
        android:max="100"
        android:progressBackgroundTint="#FBE7C6"
        android:progressDrawable="@drawable/circle_progressbar"
        android:progressTint="#edbf41" />

 

위 코드에서 반드시 구현해야 할 요소들은 아래와 같다. 

  • style="@style/Widget.AppCompat.ProgressBar.Horizontal"
    • 이렇게 설정하지 않으면, 무한 로딩 애니메이션이 발생한다. inifinite looping ..
  • android:indeterminate="false"
    • 이 값을 true 로 설정하면, Horizonatal progressBar 형태에서 무한 로딩 애니메이션이 발생한다.
    • 이 요소를 아예 제거해도 동일하게 동작한다. 즉, true 로만 설정해놓지 않으면 된다.
  • android:progressBackgroundTint="#FBE7C6"
    • progressBar 의 background 색상을 설정하는 것. 즉, 위 결과물의 progressBar 에서 남은 progress 를 나타내는 연한 노란색 부분이다.
  • android:progressDrawable="@drawable/circle_progressbar"
    • 여기서의 핵심!!! 포인트!!! @drawable/circle_progressbar 에 progressBar 의 속성(원 두께, 반지름 등등)을 지정한다. 이 drawable 파일은 아래에서 설명할 예정.
  • android:progressTint="#edbf41"
    • progress 를 나타내는 색상. 즉, 위 결과물의 progressBar 에서 progress 를 표시하는 진한 노란색 부분.

 

 

 

@drawable/circle_progressbar

원하는 progress bar 형태를 아래와 같이 drawable 파일에 지정해준다. 

<?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
            android:innerRadiusRatio="2.71"
            android:thicknessRatio="7.6"
            android:shape="ring"
            android:useLevel="false"
            android:type="sweep">
            <solid android:color="#9E9E9E" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <rotate
            android:fromDegrees="270"
            android:toDegrees="270">
            <shape
                android:innerRadiusRatio="2.71"
                android:thicknessRatio="7.6"
                android:shape="ring"
                android:angle="0"
                android:type="sweep">
            </shape>
        </rotate>
    </item>

</layer-list>

 

하나씩 설명해보면, 

첫 번째 <item> 인 👇는, progressBar의 background 부분을 설정해준다. 

item id 역시 @android:id/background 로, 위의 ProgressBar 속성에서 android:progressBackgroundTint 값을 설정해주면 이 item 의 색상이 바뀌는 것.

    <item android:id="@android:id/background">
        <shape
            android:innerRadiusRatio="2.71"
            android:thicknessRatio="7.6"
            android:shape="ring"
            android:useLevel="false"
            android:type="sweep">
            <solid android:color="#9E9E9E" />
        </shape>
    </item>

 

위의 <shape> 내의 속성을 알아보자. 

  • android:shape="ring"
    • ring(반지) 모양을 의미한다. 즉, 가운데가 뚫려있는 원이니, 바깥 원(outer circle)과 내부 원(inner circle), 원의 두께가 존재하겠지? 
  • android:innerRadiusRatio="2.71"
    • (바깥 원 지름) / (내부 원 반지름)을 의미한다.
    • 가장 위에 적어놓은 결과물의 조건을 보면, 바깥 원 지름은 76, 내부 원 반지름은 28이었으므로,
    • 76/28 = 2.71
  • android:thicknessRatio="7.6"
    • (바깥 원 지름) / (ring 두께)을 의미한다.
    • 바깥 원 지름은 76, 두께는 10이었으므로, (위에 적어놓은 조건이다)
    • 76/10 = 7.6
  • <solid android:color="#9E9E9E" />
    • 사실 이 부분은 제거해도 된다. 어차피 ProgressBar 속성에서 android:progressBackgroundTint 로 색상 조절을 할 수 있기 때문. 

 

 

이 drawable 파일 내 두 번째 <item> 내부를 알아보자. 이는 progressBar의 progress 부분을 설정해준다. 

item id 역시 @android:id/progress 로, 위의 ProgressBar 속성에서 android:progressTint 값을 설정해주면 이 item 의 색상이 바뀌는 것. 

<shape> 내 속성은 위에서 설명한 것과 동일하므로 생략.

 

 

ProgressBar.progress 설정

위에서 원하는 ProgressBar 를 구현했다. 그럼, 마지막으로 이를 코드단에서 원하는 progress 값으로 설정해주는 것만 남았다. 

 // 원하는 progress 값을 설정해주면 끝 !!
 binding.progressbar.progress = 30

 


 

끝끝. 깰꿈. 

 

반응형