지난 1, 2, 3편을 통해 리스트와 스크롤 동작의 기본은 모두 구현이 되었습니다.
[안드로이드] Custom list로 Strechable List 구현 [3] – Velocity, Runnable
[안드로이드] Custom list로 Strechable List 구현 [2] – Touch event, Scrolling
[안드로이드] Custom list로 Strechable List 구현 [1] – AdapterView 기본 구조
이제 drawChild() 를 상속해서 다양한 애니메이션을 넣을 차례입니다.
지난 편에서 드래그가 끝나면 Runnable을 이용해서 자동으로 스크롤이 계속되도록 구현했습니다.
이때 속도 값에 따라 각각의 리스트 아이템에 몇 가지 효과를 주면
자동 스크롤 되는 동안 애니메이션이 되는 것처럼 보입니다.
본인은 상상력이 빈곤한 관계로,
스크롤 되는 동안 리스트 아이템이 작아졌다 커지는 효과를 줄겁니다.
소스 다운로드 :
1. drawChild() 상속
onLayout() 에서 아이템 추가, 삭제, Layout 배치가 모두 끝나고 invalidate() 가 호출되면
각각의 리스트 아이템을 그릴 때 drawChild()를 호출하게 됩니다.
이 메서드를 상속해서 child view의 비트맵을 얻어온 다음 비트맵을 조작하는게 핵심이 되겠습니다.
그리고 child view에서 bitmap을 얻기 위해서는 child view를 생성해서 리스트에 add 할 때
child.setDrawingCacheEnabled(true) 호출이 되어야 합니다.
애니메이션 효과는 스크롤 되는 동안만 나타낼 예정이므로
속도가 임계치 이하일 경우는 super.drawChild() 를 호출해서 효과를 주지 않습니다.
private Matrix mMatrix; private Paint mPaint; private static final float SCALE_FACTOR = 0.05f;
/** * 자식 뷰를 그리는 루틴. 자식 뷰에 특별한 효과를 넣고 싶다면 이 메소드를 상속해서 수정 * Drawing cache에서 자식 뷰의 bitmap을 얻어옴 * child.setDrawingCacheEnabled(true) 설정이 되어 있어야 bitmap 추출 가능 */ @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { final Bitmap bitmap = child.getDrawingCache();
// 비트맵이 추출되지 않았거나, 속도가 임계치 이하인 경우는 효과를 주지 않음. if (bitmap == null || ( mVelocity < VELOCITY_MIN_THRESHOLD && mVelocity > VELOCITY_MIN_THRESHOLD * -1 ) ) {
// 애니메이션 효과를 주지 않는 경우 return super.drawChild(canvas, child, drawingTime); }
// 계산에 필요한 파라미터 생성 final int top = child.getTop(); final int left = child.getLeft(); int centerX = child.getMeasuredWidth()/2; int centerY = child.getMeasuredHeight()/2;
// 속도가 빠를 수도록 scale 값이 작아지도록 설정. scale factor 를 통해 조절 가능 // scale factor 가 작을수록 이미지 축소량이 작아짐 float scale = 1 / ( 1 + Math.abs(mVelocity) / VELOCITY_MIN_THRESHOLD * SCALE_FACTOR );
// Matrix 인스턴스 생성. 이미 생성되어 있다면 reset if (mMatrix == null) { // [1] mMatrix = new Matrix(); } else { mMatrix.reset(); }
// Matrix를 이용한 이미지 변환 커맨드 설정 // [2] mMatrix.preTranslate(-centerX, -centerY); // 이미지 좌 상단으로 원점 설정 mMatrix.postScale(scale, scale); // 이미지 사이즈 변경 mMatrix.postTranslate(left + centerX, top + centerY); // 아이템의 원래 위치로 이동
// Paint 설정 if (mPaint == null) { // [3] mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setFilterBitmap(true); mPaint.setAlpha(0xFF); }
// Matrix 에 따라 이미지를 캔버스에 그림. canvas.drawBitmap(bitmap, mMatrix, mPaint);
return false; } |
2. Matrix를 이용한 비트맵 변환
여기서는 scaling 만을 통해서 애니메이션 효과를 내므로 비교적 소스가 간단합니다.
[1] Matrix 인스턴스 초기화
[2] Matrix 효과 설정 (원점 변환, scaling, 원래 위치로 이동)
[3] Paint 초기화 및 설정.
Anti-alias(비트맵 변환시 계단화 방지)
Alpha(투명도 조절)
여기까지의 구현을 실행시켜 보면 스크롤이 자동으로 되는 동안
리스트의 아이템이 작아졌다 커지는 모습을 보실 수 있습니다.
첨부한 예제 소스의 패턴을 분석하고 본인의 상상력에 날개만 달아주면
얼마든지 멋진 효과를 내실 수 있을겁니다.
이 예제는 리스트의 기본 동작만을 구현한 거라 실제 사용을 위해서는
커스터마이징이 꽤 필요하실거라 생각됩니다.
예를 들어 아이템 클릭, 롱클릭 이벤트 처리는 빠져 있고
대용량의 어댑터를 달았을 때의 느려짐, 아이템 여백에 대한 처리,
아이템 사이의 divider, header, footer 등은 테스트 후 손을 봐야 합니다.
최종 소스 다운로드 :
2 thoughts on “AdapterView로 Custom List 만들기 – 4. 애니메이션 효과”
Mens Ugg Boots
(2013년 11월 18일 - 9:10 오후)It my first go to see to this site AdapterView로 Custom List 만들기 – 4. 애니메이션 효과 | Hard Copy Android , and I am actually surprised to see such a nice feature YouTube video posted here.
wow items
(2013년 11월 19일 - 11:10 오후)great wow items that would be stylish and adaptable.