AdapterView로 Custom List 만들기 – 4. 애니메이션 효과

지난 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 등은 테스트 후 손을 봐야 합니다.

 

 

최종 소스 다운로드 :  

 

 

 

Post Author: TORTUGA

TORTUGA
궁금하신 점은 새로 개편한 홈페이지의 QnA 게시판을 이용해주세요!!!!!!! http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=qna

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.

댓글 남기기

이메일은 공개되지 않습니다.