기타치는 개발자

[Android]ProgressBar IndeterminateDrawable적용하기 및 곡선 처리 본문

안드로이드

[Android]ProgressBar IndeterminateDrawable적용하기 및 곡선 처리

던킨팬더 2016. 6. 15. 14:25

파일다운로드시 IndeterminateDrawable 를 사용하여 Custom으로 화면 구성하는것을 작성해보도록 하겠습니다. 



화면은 아래와같이 다운로드 후 압축해제 등 파일 처리시 나오는 화면으로 구성되어있습니다.

다운로드 중  

파일 적용중


IndeterminateDrawable에 필요한 이미지들은 아래와 같으며 아래 이미지들이 반복되어 나타나게 됩니다.


progress_01.png

progress_02.png

progress_03.png


indeterminate_progressbar.xml


레이아웃 xml


프로그레스에 위와 같이 적용 후 해당 시점에서 progressBar.setIndeterminate(true); 을 선언해주면 위와 같이 나오게됩니다. 


하지만 안드로이드 M 버전 이하에서는 progress_01.png 이미지가 자동으로 패턴처럼 적용되어 그림과같이 나오지만 M버전에서는 이미지가 프로그래스바 크기만큼 늘어나게되어 아래와같이 나오게 됩니다. 



이경우 이미지를 패턴으로 생성하여 아래와 같이 적용하면 됩니다.

indeterminate_pattern_01.xml


위 파일을 2,3 을  적용합니다. 


그리고 위에 작성하였던 indeterminate_progressbar.xml 파일을 수정합니다.


위와같이 작성하고 빌드해보면 양쪽 끝 곡선처리가 되지 않습니다. 


그래서 본인은 해당 비트맵을 수정하여 아래와같이  Bound처리하여 해결하였습니다.



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
/*
* bitmap rounding 처리 
* */
public Drawable getRoundedCornerBitmap(Bitmap bitmap, int width, int height) {
 
    Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
 
    Canvas canvas = new Canvas(output);
 
 
    BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
 
 
    Paint paint = new Paint();
 
    paint.setAntiAlias(true);
 
    paint.setShader(shader);
 
 
    float radius = height / 2.0f;
 
    RectF rect = new RectF(0.0f, 0.0f, width, height);
 
 
    canvas.drawRoundRect(rect, radius, radius, paint);
 
    BitmapDrawable drawable = new BitmapDrawable(getResources(), output);
 
 
    return drawable;
 
}



cs

위의 메소드를 사용하여 아래와같이 구성하였습니다

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
int width = progressBar.getMeasuredWidth();
int height = progressBar.getMeasuredHeight();
Bitmap backgrounBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_prog_bar_01);
 
Rect bounds = progressBar.getIndeterminateDrawable().getBounds();
 
Drawable backgroundDrawable = getRoundedCornerBitmap(backgrounBitmap, width, height);
progressBar.setBackground(backgroundDrawable);
 
final AnimationDrawable animationDrawable = new AnimationDrawable();
 
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.progress_1);
 
Drawable back = getRoundedCornerBitmap(bitmap, width, height);
 
animationDrawable.addFrame(back, 75);
 
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.progress_2);
 
back = getRoundedCornerBitmap(bitmap, width, height);
 
animationDrawable.addFrame(back, 75);
 
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.progress_3);
 
back = getRoundedCornerBitmap(bitmap, width, height);
 
animationDrawable.addFrame(back, 75);
progressBar.setIndeterminateDrawable(animationDrawable);
progressBar.getIndeterminateDrawable().setBounds(bounds);
progressBar.requestLayout();
cs

위아같이 하였을때 setIndeterminateDrawable 가 동작하지 않습니다. 

위 이슈같은경우 http://stackoverflow.com/questions/23124366/android-progressbar-setindeterminatedrawable 를 참고하시면 

Looking at the ProgressBar source code, it looks like setIndeterminateDrawable doesn't call updateDrawableBounds so you'll have to manually set the bounds on your new drawable.


실제로 위의 소스의 getIndeterminateDrawable().getBounds() 를 가져와 처리 후 getIndeterminateDrawable().setBounds(bounds); 를 호출하여야 실제 동작하게됩니다.