차근차근/Android
안드로이드 프로그레스바 기본 사용법 [출처] 안드로이드 프로그레스바 기본 사용법|작성자 우니
http://www.androidpub.com/748389
Dialog 를 상속 받아서 customizing 해야 한다는 결론을 얻었습니다.
외국의 어느 커뮤니티에 누군가 남긴 상속 받아 재정의한 코드를 얻었구요.
가져올 때 링크를 기록하지 않았더니...다시 찾아보려고 노력해도...
찾을 수가 없네요.
여기에 감사의 글과 함께..링크를 올리고 싶었지만...다시 못찾은 관계로...패스~
감사의 마음만...가득합니다.
우선.. 상속 받은 코드는 질답게시판에 댓글로도 올렸지만.
정리하는 차원에서 여기 다시 올립니다.
아래는 Dialog 를 상속 받은 클래스입니다.
01.
class
MyProgressDialog
extends
Dialog {
02.
03.
04.
public
static
MyProgressDialog show(Context context, CharSequence title,
05.
CharSequence message) {
06.
return
show(context, title, message,
false
);
07.
}
08.
09.
public
static
MyProgressDialog show(Context context, CharSequence title,
10.
CharSequence message,
boolean
indeterminate) {
11.
return
show(context, title, message, indeterminate,
false
,
null
);
12.
}
13.
14.
public
static
MyProgressDialog show(Context context, CharSequence title,
15.
CharSequence message,
boolean
indeterminate,
boolean
cancelable) {
16.
return
show(context, title, message, indeterminate, cancelable,
null
);
17.
}
18.
19.
20.
public
static
MyProgressDialog show(Context context, CharSequence title,
21.
CharSequence message,
boolean
indeterminate,
22.
boolean
cancelable, OnCancelListener cancelListener) {
23.
MyProgressDialog dialog =
new
MyProgressDialog(context);
24.
dialog.setTitle(title);
25.
dialog.setCancelable(cancelable);
26.
dialog.setOnCancelListener(cancelListener);
27.
/* The next line will add the ProgressBar to the dialog. */
28.
dialog.addContentView(
new
ProgressBar(context),
new
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
29.
dialog.show();
30.
31.
return
dialog;
32.
}
33.
34.
public
MyProgressDialog(Context context) {
35.
super
(context, R.style.NewDialog);
36.
}
37.
}
위의 코드에서 참조하는 NewDialog 의 스타일은 다음과 같습니다. res/values/styles.xml 을 생성 시키고
아래의 코드를 넣습니다.
01.
<resources>
02.
<style name=
"NewDialog"
>
03.
<item name=
"android:windowFrame"
>
@null
</item>
04.
<item name=
"android:windowBackground"
>
@android
:color/transparent</item>
05.
<item name=
"android:windowIsFloating"
>
true
</item>
06.
<item name=
"android:windowContentOverlay"
>
@null
</item>
07.
<item name=
"android:windowTitleStyle"
>
@null
</item>
08.
<item name=
"android:windowAnimationStyle"
>
@android
:style/Animation.Dialog</item>
09.
<item name=
"android:windowSoftInputMode"
>stateUnspecified|adjustPan</item>
10.
<item name=
"android:backgroundDimEnabled"
>
false
</item>
11.
<item name=
"android:background"
>
@android
:color/transparent</item>
12.
</style>
13.
14.
</resources>
Dialog 를 이용하기 때문에.. 그리고.. WebView 에서 PageFinished 이벤트가 있기 때문에,
쓰레드를 사용할 필요가 없다는 것을 알게 되었습니다.
1.
package
pkg.WebViewTest;
01.
import
android.app.Activity;
02.
import
android.app.Dialog;
03.
import
android.content.Context;
04.
import
android.os.Bundle;
05.
import
android.os.Handler;
06.
import
android.os.Message;
07.
import
android.util.Log;
08.
import
android.view.MotionEvent;
09.
import
android.view.View;
10.
import
android.view.ViewGroup.LayoutParams;
11.
import
android.webkit.WebView;
12.
import
android.webkit.WebViewClient;
13.
import
android.widget.Button;
14.
import
android.widget.ProgressBar;
15.
import
android.widget.TextView;
1.
public
class
WebViewTest
extends
Activity {
2.
/** Called when the activity is first created. */
3.
4.
public
MyProgressDialog progressDialog;
1.
@Override
2.
public
void
onCreate(Bundle savedInstanceState) {
3.
super
.onCreate(savedInstanceState);
4.
5.
setContentView(R.layout.main);
6.
wvc = (WebView)findViewById(R.id.WebView01);
7.
wvc.getSettings().setJavaScriptEnabled(
true
);
01.
wvc.loadUrl(
"http://m.naver.com"
);
02.
progressDialog = MyProgressDialog.show(
this
,
""
,
""
,
true
,
true
,
null
);
03.
04.
wvc.setWebViewClient(
new
WebViewClient()
05.
{
06.
@Override
07.
public
void
onPageFinished(WebView view, String url)
08.
{
09.
wvc.setVisibility(View.VISIBLE);
10.
if
(progressDialog!=
null
)
11.
progressDialog.dismiss();
12.
}
13.
});
14.
}
1.
}
많은 상용 앱에서 wheel 만 돌아가는 로딩 이미지를 사용하는데, 이것을 구현하기 위한 코드는 찾기 힘들었습니다.
다행히도 잘 찾아서..잘 사용하게 되었습니다.
이것 또한 누군가에게...도움이 되기를 기원합니다. 휴~~~
http://coreskill.tistory.com/262
Custom Progress Dialog
POSTED AT 2014/05/22 23:25 | POSTED IN ANDROID/TIPS 자료/** * dialog-theme: style 적용 * setContentView()로 커스텀다이얼로그 가능 * * @return dialog */ public Dialog getProgressDialog() { Dialog dialog = new Dialog(this, R.style.dialog); dialog.setContentView(R.layout.dialog_progress); dialog.setCanceledOnTouchOutside(false); return dialog; }
<!-- styles.xml 상속으로 Theme.Dialog windowBackground: 배경은 투명 windowNoTile : 타이틀이 없는 다이얼로그 --> <style name="dialog" parent="@android:style/Theme.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowNoTitle">true</item> </style>
<!-- dialog_progress.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ProgressBar
style="@style/loading"
android:layout_width="80dip"
android:layout_height="80dip"
android:background="@drawable/dialog_full_holo_light"
android:padding="22dip"
/>
</LinearLayout>
<style name="loading">
<item name="android:indeterminateDrawable">@drawable/progress_ani</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">400</item> </style>
<!-- progress_ani.xml --> <?xml version="1.0" encoding="utf-8"?> <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/spinner_76_inner_holo" android:pivotX="50%" android:pivotY="50%" />
http://blog.naver.com/PostView.nhn?blogId=unsrhythm&logNo=220100360885
[안드로이드 기초] 프로그레스바(ProgressBar) |
● 프로그레스바는 '진행 바' 정도로 생각하면 될텐데요. 어플을 실행하거나 뭔가를 다운 받을때 진행 정도를 표현해주는 것들입니다. 많이들 봤겠지만 이것은 원형과 막대형이 있구요. 또 이것들을 Dialog안에 넣어서 새로운 창으로 띄워서 표현 할 수도있습니다. 예제를 만들어가면서 일반 원형, 막대형과 새로운 창을 띄워서 나타나게 하는 형태까지 구현해 보겠습니다.
● 다음과 같이 '원형'과 '막대형' 프로그레스바를 두개 설치하고, 토글버튼 두개, 일반 버튼 두개를 배치를 했습니다.프로그램을 실행할때는 보이지 않다가 첫번째 토글버튼을 클릭하면 원형바가 나타나 작동을 하고, 두번째 토글버튼은 막대형바가 나타나 진행을 합니다. 일반 버튼은 상자를 따로 화면에 띄워서 진행바들을 실행을 시키게 됩니다.
● 액티비티 파일을 작성하겠습니다.
먼저 현재 액티비티와 각각의 객체들을 선언을 합니다.
● 다음으로는 두개의 진행바(원형, 막대형)이 처음 어플을 실행할때는 나타나지 않도록 다음과 같은 코드를 작성하겠습니다.
● 토글버튼을 "Id"값으로 찾아서 위에서 선언한 객체" tb1"과 "tb2"에 담고, 이것들에 대한 클릭이벤트를 작성합니다.
코드 내용을 보면 첫번쨰 토글버튼을 클릭헤서 'On'이 되면 원형 진행바가 나타나게 되고, 'Off'상태가 되면 사라지게 됩니다. 두번째 토글버튼에 같은 방법으로 막대형 진행바를 설정합니다. 그리고 두번째 토글버튼을 눌렀을때 'On' 상태일때 스레드를 실행을 하고 Off일때는 스레드를 종료하게 됩니다.
● 다음은 두개의 버튼에 대한 이벤트를 작성합니다.
두개의 버튼을 "Id"값으로 찾아서 선언했던 객체에 담고, 클릭이벤트를 정의 합니다. 첫번째 버튼에는 원형 진행상자가 실행되다가 5초 후에 자동으로 사라지는 이벤트를 작성하고, 두번째는 막대형 진행상자가 실행되게 합니다. 스레드 방식을 사용하는데, 진행률이 100%가 되면 사라지게 합니다.
● 위에 적용할 스레드를 작성하도록 하겠습니다.
스레드를" volatile"로 선언해서 한번 사용하면 사라지게 합니다. 단어의 뜻대로 휘발성이라는 의미로 한번 사용하고 나서 사라지게 하는것입니다. 그리고 종료하는 메서드와 동기화하기 위해서 syncrhonized를 사용합니다. 객체를 생성하고, 시작전의 진행률을 '0'으로 설정해서 스레드를 시작하게 됩니다. 종료할때는 스레드가 존재할때만 종료를 하고, 객체를 'null'로 초기화 시킵니다. 다음으로 막대형 진행상자를 화면에서 사라지게 하고 두번째 토글버튼을 'Off'시킵니다.
● 다음으로 막대형 진행바의 이동 상태를 0.1초 간격으로 갱신해서 진행하도록 하는 코드입니다.
코드 내용을 살펴보면 백그라운드에서 실행하는 Runnable 객체를 생성하고, Run()메서드로 실행명령을 정의합니다. If문을 사용해서 현재 스레드가"Thread1"일때만 실행을 하게 합니다. 처음 진행률은 '0'으로 설정하고 '100'이 될때까지 반복하게 합니다. 0.1초마다 진행을 하며 핸들러에 메세지를 전달하여, 반복할 때마다 실행할 명령을 핸들에서 정의할 수 있도록 합니다.
두번째로 메세지를 수신할 때마다 실행하는 메서드를 정의합니다. 진행률은 1씩 증가하고 진행바에 표시를 하며, 두번째 토글버튼에 출력하게 합니다. 진행률이 100이되면 스레드를 중단시킵니다.
● 다음으로 원형 진행상자를 출력하고 5초후에 자동으로 사라지게 하는 코드를 작성하겠습니다.
진행상자를 객체에 담고 화면에 나타나게 하며, 제목은 "Loading..." 으로 하고 인내문은 "Please wait.."로 설정해서 진행상자를 5초후에 사라지게 하는 메서드입니다.
진행상자를 사라지게 할 endLoader클래스를 'TimeTask'클래스를 상속받아서 생성합니다. Run()메서드를진행상자가 있을때만 상자가 사라지게 하고 'null'로 초기화 하는 메서드를 작성합니다.
● 다음은 막대형 진행상자를 생성하고 소멸시키는 코드를 작성하겠습니다.
진행상자 객체를 생성하고 스레드 객체를 "volatile"로 선언하고 스레드를 생성해서 실행하고 진행상자를 출력하는 메서드를 작성합니다. 이어서 진행상자를 종료하는 메서드를 작성하는데요. 스레드가 있으면 null로 초기화 및 중단 하고, 화면에서 사라지게 합니다.
●마지막으로 위쪽의 스레드에서 호출하는 backgroundTread2 실행 객체를 작성합니다.
스레드에서 호출했을 때 실행할 내용을 run()메서드에 작성하는데요. 현재 실행중인 스레드가 막대형 진행상자에 대한것일때만 실행하도록 합니다. 진행률을 0으로 초기화 하고, 전체를 100으로 설정하고 100이 될때까지 진행하게 합니다. 핸들러에 메세지를 보내고, 0.1초마다 반복 하도록 sleep()를 사용합니다.
두번째로 핸들러 메세지가 수신될때 실행하는 메서드를 정의하는데요. 진행률은 1씩 증가하고 막대진행바에 표시하며, 진행상자의 메세지를 백분률로 표시하는 내용입니다.
● 가상기기에서 실행을 해보면서 어떻게 나타나는지 살펴보겠습니다.
<iframe width="640" height="360" src="http://videofarm.daum.net/controller/video/viewer/Video.html?vid=v89bfzp1NJpJ2AAJLLL15p1&play_loc=daum_tistory&alert=true" frameborder="0" scrolling="no"></iframe>
http://wpkc.egloos.com/5179291
앞서 쓰레드와 핸들러를 이용한 메시징과 작업 스케줄링을 살펴봤습니다. 이것과 같은 개념이지만 이걸 프로그레스 바로도 처리할 수 있습니다. 이때는 진행과정에 해당하는 메시지를 따로 보여줄 필요는 없습니다. 프로그레스 바 자체가 진행중이라는 걸 의미하니까요.
프로그레스 바는 말 그대로 막대 바(bar) 형태와 원형으로 돌아가는 스피너(spinner) 두 가지가 있는데 여기서는 스피너를 이용합니다. 쓰레드와 핸들러가 필요하고 프로그레스 바는 `프로그레스 다이얼로그`입니다.
쓰레드를 시작시켜 주는 부분 바로 위에 프로그레스 다이얼로그를 위치시킵니다. setProgressStyle에서STYLE_SPINNER로 해야 원형이 됩니다. 참고로 막대 바 형태는 STYLE_HORIZONTAL입니다.
일정시간이 지나 프로그레스 다이얼로그가 사라진 후 처리될 코드들은 handleMessage(Message msg) 메써드의 progressDialog.dismiss() ; 다음에 넣어줍니다.
그렇게 앱이 실행된 모습입니다. 이전과 똑같이 처음엔 아무것도 나타나지 않습니다.
여기서 버튼을 누르면 프로그레스 다이얼로그가 뜨면서 진행중임을 나타냅니다.
잠시 후 결과가 나타납니다.
안드로이드/Android Handler를 사용한 ProgressDialog 띄우기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package arabiannight.tistory.com.progressdialog2; import android.app.Activity; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; public class TestProgressDialog2Activity extends Activity { private Handler mHandler; private ProgressDialog dialog; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); mHandler = new Handler(); dialog = new ProgressDialog( this ); dialog.setMessage( "잠시만 기다려 주세요." ); dialog.setCancelable( false ); dialog.setButton( "ok" , new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface idialog, int which) { if (dialog != null && dialog.isShowing()){ dialog.dismiss(); } } }); dialog.setButton2( "cancel" , new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface idialog, int which) { if (dialog != null && dialog.isShowing()){ dialog.dismiss(); } } }); dialog.show(); mHandler.postDelayed(mRunnable, 5000 ); } private Runnable mRunnable = new Runnable() { @Override public void run() { if (dialog != null && dialog.isShowing()){ dialog.dismiss(); } } }; } |
style="?android:attr/progressBarStyle" 중간원
style="?android:attr/progressBarStyleInverse" 중간원 반전
style="?android:attr/progressBarStyleHorizontal" 가로형
style="?android:attr/progressBarStyleLarge" 큰원
style="?android:attr/progressBarStyleLargeInverse" 큰원 반전
[안드로이드] 프로그레스 다이얼로그(ProgressDialog) 생성하기
프로그레스 다이얼로그 ( Progress Dialog ) 는 AlertDialog 클래스를 상속받은 클래스 입니다. 이것은 끝나는 시점이 명확하지 않은 상태의 태스크에 대한 진행상황을 '진행바퀴' 로 보여줍니다.
끝나는 시점이 정해진 태스크라면 좀 더 명확하게 '진행바' 로 보여주는것도 좋겠네요
이 다이얼로그는 버튼을 제공할 수도 있습니다. ProgressDialog 의 구현은 ProgressDialog.show() 메소드를 호출하는 것만으로 처리할 수 있습니다.
show() 메소드는 모두 static 메소드라는 점에 주의하시면 되겠습니다.
12 |
|
ProgressDialog dialog = ProgressDialog.show(AndroidTest.this, "", "로딩 중입니다. 잠시 기다려주세요", true);
show() 메소드의 첫번째 인자는 어플리케이션의 컨텍스트, 두번재는 다이얼로그 타이틀, 세번째는 텍스트 내용, 네번째는 '진행바'에서 사용되는 루프 진행 여부를 나타냅니다.
프로그레스 다이얼로그의 디폴트 스타일은 '진행바퀴' 입니다.
명확한 진행율을 보여주는 진행바를 만들기 위해선 아래와 같은 방법을 일반적으로 사용합니다.
2. 진행 스타일을 setProgressStyle() 메소드에 "STYLE_xxx" 로 지정하고 그외 속성들을 지정합니다
3. 다이얼로그 표시를 위해 show() 메소드를 호출 하거나, onCreateDialog() 에서 ProgressDialog 객체를 리턴해도 됩니다.
4. 전체 값을 setProgress() 로 지정하거나 incrementProgressBy(int) 메소드로 현재 진행양에 증가분 값을 더할 수 있습니다.
123456 |
|
ProgressDialog progressDialog; progressDialog = new ProgressDialog(AndroidTest.this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("로딩중입니다..."); progressDialog.setCancelable(false); progressDialog.show();
직접 소스코드를 테스트 해보시는 분들도 계시겠지만, 직접 테스트해보면 다이얼로그가 시작되면 그 다이얼로그가 끝나서 종료되어 끝나기 전에는 해당 액티비티에서 "BACK" 버튼을 눌러도 반응을 하지 않습니다.
진행상태라는것의 특성상 어떤 진행 상태는 오래걸릴수도 있고 다른 기타 이유들 때문에 별도의 스레드에서 처리하고 , 메인 스레드는 계속 사용자에게 즉각 반응을 해야되는데요, 이 작업을 위해선 스레드를 새로 생성 후 핸들러를 이용하여 메인스레드에게 결과를 알려주는 방식을 써야 합니다.
진행상태 표시와 처리를 위하여 , 별도의 스레드를 만들고 그 스레드는 진행이 이루어질 때 마다 핸들러를 통해 메인 스레드로 알려주면 됩니다. 그러면 메인 액티비티에서 Progress 다이얼로그를 업데이트하게 하면 되겠지요.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
|
package exam.androidtest;
import android.app.Activity;import android.app.Dialog;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;
public class NotificationTest extends Activity { static final int PROGRESS_DIALOG = 0; Button button; ProgressThread progressThread; ProgressDialog progressDialog;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
button = (Button) findViewById(R.id.btn); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { showDialog(PROGRESS_DIALOG); } }); }
protected Dialog onCreateDialog(int id) { switch (id) { case PROGRESS_DIALOG: progressDialog = new ProgressDialog(NotificationTest.this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("Loading..."); progressThread = new ProgressThread(handler); progressThread.start(); return progressDialog; default: return null; } }
// 핸들러는 정의하여 스레드가 메시지를 보내면 프로그레스를 업데이트 합니다. final Handler handler = new Handler() { public void handleMessage(Message msg) { int total = msg.getData().getInt("total");
progressDialog.setProgress(total); if (total >= 100) { dismissDialog(PROGRESS_DIALOG); progressThread.setState(ProgressThread.STATE_DONE); } } };
/** 프로그레스를 처리하는 클래스를 내부 클래스로 정의. */ private class ProgressThread extends Thread { Handler mHandler; final static int STATE_DONE = 0; final static int STATE_RUNNING = 1; int mState; int total;
ProgressThread(Handler h) { mHandler = h; }
public void run() { mState = STATE_RUNNING; total = 0; while (mState == STATE_RUNNING) { try { Thread.sleep(100); } catch (InterruptedException e) { // 에러처리 } Message msg = mHandler.obtainMessage(); Bundle b = new Bundle(); b.putInt("total", total); msg.setData(b); mHandler.sendMessage(msg); total++; } }
// 현재의 상태를 설정하는 메소드 public void setState(int state) { mState = state; } }}
- 글쓴이: http://underclub.tistory.com/314
'차근차근 > Android' 카테고리의 다른 글
앱 업데이트 설치후 자동 시작방법 (0) | 2014.09.16 |
---|---|
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length (0) | 2014.09.16 |
[Android] Custom ProgressBar - 프로그래스바 모양 변경 (0) | 2014.09.15 |
Activity가 아닌 클래스에서 Activity를 실행할 수 있나요? (0) | 2014.09.02 |
안드로이드 TIP] Activity가 아닌 곳에서 Intent 하기 (0) | 2014.09.02 |
'차근차근/Android'의 다른글
- 현재글안드로이드 프로그레스바 기본 사용법 [출처] 안드로이드 프로그레스바 기본 사용법|작성자 우니