ProgressBar란?
ProgressBar는 작업의 진행 정도를 표시하거나 작업이 진행 중임을 사용자에게 알려주는 수단 중 하나다. 또한, 어떤 일의 진행 상태를 중간 중간 보여줄 수 있는 가장 좋은 방법 중 하나이다. ProgressBar는 대표적으로 두 가지 형태가 존재한다.
속성 | 설명 |
막대모양 | 작업의 진행 정도를 알려주는 막대모양으로 표시한다. |
원 모양 | 작업이 진행 중임을 알려준다. 원 모양으로 된 ProgressBar가 반복적으로 표시된다. |
XML 레이아웃에 ProgressBar를 추가할 때는 <ProgreeBar>태그가 사용되며, ProgressBar가 갖는 값의 최대 범위는 max속성으로 설정하고 현재 값은 progree속성으로 설정한다. 예를 들자면, 값의 최대 범위가 100이고 max값을 100으로 설정했을 때 진행률이 50%라면 max값이 100이므로 progress값을 50으로 설정하면 된다. 진행률에 변경이 있다면 progree속성으로 설정되었던 값을 바꾸면 된다. 자바 코드에서 ProgressBar의 현재 값을 바꿀 때 사용하는 대표적인 메서드들은 다음과 같다.
void setProgress (int progress)
void incrementProgressBy(int diff)
setProgree() 메서드는 정수 값을 받아 ProgressBar의 현재 값으로 설정한다.
incrementProgressBy() 메서드는 현재 설정되어 있는 값을 기준으로 값을 더하거나 뺄 때 사용한다.
ProgreeBar는 항상 보일 필요가 없으므로 화면에서 차지하는 공간을 줄일 수 있도록 타이틀바에 ProgressBar를 표시할 수 도 있다. 이러한 기능은 윈도우 속성으로 정의되어 있으므로 다음과 같은 메서드를 사용하면 된다.
requestWindowFeature(Window.FEATURE_PROGRESS);
타이틀 부분에 표시되는 ProgressBar는 범위를 따로 지정할 수 없기 때문에 디폴트 값인 0부터 10000사이의 값을 고정적으로 가진다. 따라서 진행률이 50%인 경우에는 ProgressBar의 현재 값을 5000으로 설정해야 한다.
타이틀바에 ProgressBar를 보여주는 방식은 화면의 공간을 절약하는 매우 직관적인 방식이긴 하지만 앱을 만들 때는 타이틀 부분을 보이지 않게 설정하는 경우가 많으므로 사용할수 없는 경우도 생긴다.
이제 예제를 통하여 Progress바를 사용해보자.
-막대모양 ProgreeBar-
본 예제는 쓰레드를 활용하여 ProgressBar를 버튼을 통하여 진행률을 컨트롤한것을 구현한것이다.
-코드-
activity_main.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
tools:context=".MainActivity"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<ProgressBar
android:layout_height="73dp"
android:layout_width="match_parent" style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/progressBar"/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/btn_execute"
android:text="실행"/>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/btn_stop"
android:text="중지"/>
</LinearLayout>
MainActivity.java
package com.lwm.thread;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.lwm.thread.R;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main_Activity";
private Button btnExecute, btnStop;
private ProgressBar progressBar;
private int value=0;
private BackgroundTask task;
private Boolean threadStatus;
class BackgroundTask extends AsyncTask<Integer, Integer, Integer>{
//타겟 호출 직전 실행
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setProgress(value);
threadStatus=true;
Log.d(TAG, "onPreExecute: ");
}
//Target Run
@Override
protected Integer doInBackground(Integer... integers) { //스레드 실행 시 인수 받음
Log.d(TAG, "doInBackground: ");
// publishProgress(10); //onProgressUpdate를 호출
while (threadStatus){
value=value+5;
publishProgress(value);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
return -1;
}
if(value>100){
return 1;
}
}
//정상적으로 수행됐으면 1, 아니면 -1 리턴 식으로 사용
return -1;
}
//UI 스레드 그림을 그리는 메서드
@Override
protected void onProgressUpdate(Integer... values) { //publish 인수 받음
Log.d(TAG, "onProgressUpdate: ");
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}
//타겟 호출 이후 실행
@Override
protected void onPostExecute(Integer integer) { //doInBackground 리턴 값 받음
Log.d(TAG, "onPostExecute: ");
super.onPostExecute(integer);
if (integer == 1) {
Toast.makeText(MainActivity.this, "다운로드 완료", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mInit();
task=new BackgroundTask();
mListener();
}
private void mInit(){
btnExecute=findViewById(R.id.btn_execute);
btnStop=findViewById(R.id.btn_stop);
progressBar=findViewById(R.id.progressBar);
}
private void mListener(){
btnExecute.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
task=new BackgroundTask();
task.execute();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
threadStatus=false;
}
});
}
}
-막대모양 ProgreeBar와 원 모양 ProgressBar 혼용 예제-
타이틀 부분에 막대 ProgressBar가 존재하며 '보여주기'를 클릭하면 원 모양 ProgressBar가 보여진다. 화면 아무곳이나 클릭하면 원 모양 ProgressBar가 사라진다.
-코드-
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="보여주기" />
</LinearLayout>
</LinearLayout>
MainActivity.java
package com.example.test;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends AppCompatActivity {
ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setIndeterminate(false);
progressBar.setProgress(80);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog = new ProgressDialog(MainActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage("데이터 확인중");
dialog.show();
}
});
}
}
-또다른 원 모양 ProgressBar 예제-
본 예제는 쓰레드를 활용하여 일정시간 ProgressBar가 보여지고 일정시간이 지나면 ProgreeBar를 invisible하게 구현한것이다.
-코드-
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/pgb_download"
style="?android:attr/progressBarStyle"
android:layout_width="213dp"
android:layout_height="219dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.example.test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ProgressBar pgbDownload;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//컴포넌트 초기화
initComponent();
//다운로드 5초
imageDownload();
}
private void imageDownload() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
}catch (InterruptedException e) {
e.printStackTrace();
}
pgbDownload.setVisibility(View.INVISIBLE);
}
}).start();
}
private void initComponent() {
pgbDownload = findViewById(R.id.pgb_download);
}
}
'Android' 카테고리의 다른 글
Android / 간단한 계산기 앱 만들기 (0) | 2020.07.22 |
---|---|
Android / 버튼 클릭시 숫자가 증감하는 로직 (2) | 2020.07.22 |
Android/ AppCompat위젯으로 버튼 생성하고 클릭 이벤트 주기 (0) | 2020.07.22 |
Android / ScrollView (0) | 2020.07.21 |
Android / 액션바 삭제하기 (0) | 2020.07.21 |