안드로이드 프로그레스바(ProgressBar) 기본 사용법. (How to use an Android ProgressBar)

2017. 6. 22. 19:29


1. 안드로이드 프로그레스바(ProgressBar)

안드로이드에서 프로그레스바(ProgressBar)는, 앱 내에서 어떠한 작업이 수행될 때, 그 작업의 진행 상태를 시각적으로 보여주기 위해 사용하는 뷰(View) 위젯입니다. 다른 여러 종류의 UI 프레임워크에서도 기본적으로 제공되는 요소이며, 어떤 프레임워크에서든 "수치 값 또는 작업 진행 상태 표시"라는 공통적인 목적으로 사용됩니다.

다양한 UI 프레임워크의 프로그레스바


안드로이드의 프로그레스바(ProgressBar)는 진행 상태를 표시함에 있어 두 가지 모드를 지원합니다. 불확정적(indeterminate) 상태 표시 모드와 확정적(determinate) 상태 표시 모드입니다. 이 두 가지 모드를 구분하는 기준은, 진행 상태를 표시할 때 명확한 수치 또는 범위 값을 지정하여 현재의 진행 단계를 표시할지(=determinate), 아니면 명확한 수치 또는 범위 값을 사용하지 않고 막연히 작업이 진행되고 있음을 표시할지(=indeterminate) 여부입니다.

1.1 불확정적(indeterminate) 상태 표시 모드

불확정적(indeterminate) 상태 표시 모드는 단어 의미 그대로, 작업의 진행 단계 결정 또는 완료 시점이 확정되지 않은 경우 사용하는 모드입니다. 즉, 작업 진행이 언제 완료될 것인지를 정확한 수치 또는 범위 값으로 계산할 수 없는 경우를 말하는 것이죠.


예를 들어, 네트워크를 통해 서버에 요청 메시지를 보내고 그에 대한 응답 메시지를 받는 작업을 생각해보죠. 이 경우, 서버에 요청 메시지를 보내고 나서 응답을 받기까지의 시간 중, 현재 그 작업이 정상적으로 진행되고 있음을, 프로그레스바(ProgressBar)를 사용하여 시각적으로 표시할 수 있습니다.


그런데 서버로 보낸 요청에 대한 응답은 언제 도착할지 그 시간을 예상하기가 힘듭니다. 네트워크 지연(delay)으로 인해 수초 또는 수십초가 걸릴 수도 있고, 네트워크 통신 오류로 아예 응답을 받지 못할 수도 있습니다. 그러므로 이런 경우에는 작업의 진행 완료 시점을 정확히 계산하기 힘들기 때문에, 진행 단계를 보여주기 위해 프로그레스바(ProgressBar)를 사용하는 것이 아니라, 프로그레스바(ProgressBar)의 단순한 움직임을 통해 현재 작업이 진행 중이라는 표시정도만 하는 것이 더 좋은 상황이죠.


불확정적(indeterminate) 상태 표시 모드는 프로그레스바(ProgressBar)의 기본 동작 모드이며, 화면에 표시될 때 특정 값을 표시하지 않고 반복적인 애니메이션을 통해 어떠한 작업이 진행 중임을 보여줍니다.


프로그레스바(ProgressBar)의 기본 값이므로, "<ProgressBar>"에 어떠한 속성도 지정하지 않으면 불확정적(indeterminate) 모드로 동작합니다.

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progress1" />

불확정적(indeterminate) 모드에서 애니메이션이 어떻게 동작하는지는 [Progress & activity]에서 확인할 수 있습니다.

1.2 확정적(determinate) 상태 표시 모드

프로그레스바(ProgressBar)의 확정적(determinate) 상태 표시 모드는 불확정적(indeterminate) 상태 표시 모드와는 다르게, 진행중인 작업의 진행 상태를 수치적으로 정확히 표시하거나, 양(quantity), 갯수(amount), 퍼센트(percent)를 보여주기 위해 사용합니다.


예를 들자면, 파일을 복사하는 과정에서의 복사된 파일 사이즈 표시, 날씨 앱 등에서의 현재 기온 표시, 음악 파일 재생 시 남아 있는 재생 시간 표시 등에서 확정적(determinate) 상태 표시 모드를 적용할 수 있습니다.


프로그레스바(ProgressBar)를 확정적(determinate) 상태 표시 모드로 사용하기 위해서는 "<ProgressBar>"의 style 속성을 "Widget_ProgressBar_Horizontal"로 지정하고, progress 속성을 사용하여 값을 지정하면 됩니다.

    <ProgressBar
        android:id="@+id/progress2"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:progress="25" />

그리고 앱 실행 중 progress 값을 바꾸기 위해서는 setProgress() 함수를 사용할 수 있습니다. (참고로 setProgress() 함수는 불확정적(indeterminate) 모드에서는 동작하지 않습니다.)

setProgress() 함수


2. 프로그레스바(ProgressBar) 사용하기. (확정적(determinate) 상태 표시 모드)

그럼 지급부터 간단한 앱 작성을 통해, 프로그레스바(ProgressBar)를 어떻게 사용하는지 알아보겠습니다.


예제에서 작성하는 앱은 다음과 같은 화면으로 구성됩니다.

프로그레스바 예제 화면 구성


예제를 통해 작성되는 앱은, 화면에 배치된 에디트텍스트에 0~100 사이의 값을 입력하고 "Apply" 버튼을 클릭하면, 입력된 값을 프로그레스바에 표시하는 간단한 동작을 수행합니다.

2.1 MainActivity의 레이아웃 구성.

가장 먼저, MainActivity에 표시될 레이아웃 리소스 XML 파일을 작성합니다.

[STEP-1] "activity_main.xml" - MainActivity의 Layout 구성.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.ppottasoft.progressbarbasicexample.MainActivity"
    tools:showIn="@layout/activity_main">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_margin="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ProgressBar
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:paddingTop="12dp"
                style="@android:style/Widget.ProgressBar.Horizontal"
                android:id="@+id/progress" />

            <EditText
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:inputType="number"
                android:id="@+id/edit"
                android:text="0" />

            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:id="@+id/button"
                android:text="Apply" />

        </LinearLayout>
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

2.2 버튼 클릭 이벤트 처리.

다음, 화면에 있는 "Apply" 버튼을 클릭하면 에디트텍스트에 입력된 숫자 값을 프로그레스바에 적용하는 코드를 작성합니다. 이 때, 에디틑텍스트에 입력된 값을 검사하여, 잘못된 포맷으로 저장되었거나, 0과 100 사이의 범위를 넘어서는 경우 토스트(Toast) 메시지로 메시지를 출력하도록 만듭니다.

[STEP-2] "MainActivity.java" - onCreate() 함수에서 버튼 클릭 이벤트 처리.
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속
        Button applyButton = (Button) findViewById(R.id.button) ;
        applyButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText valueEditText = (EditText) findViewById(R.id.edit) ;

                try {
                    // 문자열을 숫자로 변환.
                    int value = Integer.parseInt(valueEditText.getText().toString());
                    if (value < 0 || value > 100) {
                        Toast toast = Toast.makeText(MainActivity.this, "0 to 100 can be input.",
                                Toast.LENGTH_SHORT);
                        toast.show();
                    } else {
                        // 변환된 값을 프로그레스바에 적용.
                        ProgressBar progress = (ProgressBar) findViewById(R.id.progress) ;
                        progress.setProgress(value) ;
                    }
                } catch (Exception e) {
                    // 토스트(Toast) 메시지 표시.
                    Toast toast = Toast.makeText(MainActivity.this, "Invalid number format",
                            Toast.LENGTH_SHORT);
                    toast.show();
                }

            }
        }) ;
    }
}

3. 예제 실행 화면.

예제를 작성하고 실행하면 다음과 같은 화면이 표시됩니다.

프로그레스바 예제 실행 화면 1


화면의 에디트텍스트에 0~100 사이의 값을 입력하고 "Apply" 버튼을 클릭하면, 입력된 값이 프로그레스바에 표시되는 것을 확인할 수 있습니다.

프로그레스바 예제 실행 화면 2


4. 프로그레스바의 기본(default) 값과 최대(max) 값.

4.1 프로그레스바의 최대(max) 값 변경. (max 속성)

예제에서 프로그레스바를 사용할 때 setProgress() 함수를 통해 전달한 값은 0~100 사이의 정수 값입니다. 즉, 프로그레스바에 지정할 수 있는 최대 값이 100이라는 말인데요, 이 최대 값은 max 속성을 통해 변경이 가능합니다. 하지만 max 값을 줄이거나, 늘린다고 하더라도, 프로그레스바의 크기에는 영향을 주지 않습니다.

  * android:max - 프로그레스바의 최대(max) 값 지정.
        > 정수 값 사용. (예. 100)

아래는 max 속성에 1000을 지정한 예제 입니다.

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:max="1000"
        android:id="@+id/progress" />

아래 그림은 setProgress() 함수를 사용하여 각각 50, 100, 500, 1000의 값을 지정했을 때 표시되는 화면입니다.

프로그레스바 예제 실행 화면 3


만약 max 값을 넘어서는 값을 setProgress()를 통해 전달하면, max 값에 맞춰집니다.

4.2. 프로그레스바의 기본(default) 값 변경. (progress 속성)

앱 실행 시, 최초 표시되는 프로그레스바의 값을 지정하기 위해서는 progress 속성을 사용합니다. setProgress() 함수에 매칭되는 속성이죠.

  * android:progress - ProgressBar의 기본 값 지정.
        > 정수 값 사용. (예. 100)
        > 0과 max 사이의 값 지정 가능. (max의 기본 값은 100)

다음은 max 속성과 progress 속성을 사용하여 최초 화면에 표시되는 기본 값을 지정하는 예제입니다.

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:progress="7"
        androdi:max="10"
        android:id="@+id/progress" />

프로그레스바 예제 실행 화면 4


5. 참고

.END.


ANDROID 프로그래밍/PROGRESS