출처 : http://blog.naver.com/PostView.nhn?blogId=huniwha&logNo=70097340528

* 안드로이드에서의 에니메이션은 전통적인 프레임 방식 에니메이션과

Tweening 을 통한 에니메이션 방식이 있다.




* 뷰 에니메이션

안드로이드는 아이폰과 같이 뷰의 간단한 변형에 관련한 에니메이션 처리를 지원한다. 

레이아웃 에니메이션과 각 구성요소의 에니메이션으로 나눌수 있다.


처리할 수 있는 에니메이션은 아래와 같으며, 코드상에서의 클래스명이다.

AlphaAnimation - 투명도 변환

RotateAnimation - 회전

ScaleAnimation - 크기 변환

TranslateAnimation - 위치 이동



1. xml 정의

에니메이션 순서를 XML 로 정의해 놓고, 해당 XML 을 불러 에니메이션을 동작케 하는 형태로

구성되는데 프로젝트내의 res/anim/ 폴더에 정의된다.

아마도 가장 많이 사용되는게 페이드 인일것 같은데..아닌가? 음..

암튼 페이드인의 경우 알파 에니메이션을 사용하면 된다.

페이드인 에니메이션

<?xml version="1.0" encoding="utf-8"?>

<alpha xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/accelerate_interpolator"

android:fromAlpha="0.0"

android:toAlpha="1.0"

android:duration="300" />


해당 에니메이션을 지정하고, 각 값들을 설정하는 것으로 끝이다..

페이드 인은 투명값이 0에서 완전 투명인 1로 이동하는 것을 말하는데,

fromAlpha="0.0" / toAlpha="1.0" 으로 페이드 인

 

반대로 아래와 같은 경우는 페이드 아웃 에니메이션이다.

<?xml version="1.0" encoding="utf-8"?>

<alpha xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/accelerate_interpolator"

android:fromAlpha="1.0"

android:toAlpha="0.0"

android:duration="300" />

 

각 에니메이션별로 속성값이 있는데,

 

alpha

fromAlpha

toAlpha

 

scale

fromXScale

toXScale

fromYScale

toYScale

pivotX

pivotY

fillAfter

fillBefore

 

rotate

fromDegrees

toDegrees

toYScale

pivotX

pivotY

startOffset

 

translate

toXDelta

toYDelta

 

등 에니메이션에 따른 속성이 정의되어 있다.


 

만약 여러 에니메이션을 설정하고 한다면

<set> 태그를 사용할 수 있다.


왼쪽에서 미끄러져 나오는 에니메이션과 회전 에니메이션

<set xmln:android:="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/accelerate_interpolator"

<translate android:fromXDelta="100%p"

android:toXDelta="0"

android:duration="150" />


<rotate andriod:fromDegrees="0"

android:toDegrees="90"

android:fillAfter="true"

android:startOffset="800"

android:duration="150" />

</set>

이처럼 <set> 태그로 여러 에니메이션을 정의할 수 있고, 각각의 에니메이션에

공통적으로 적용할 내용을 set 에서 지정할 수 있다. 위의경우 duration이 동일하므로

<set android:duration="150"

으로 공통사항으로 지정해도 된다.


 // ApiDemos 의 회전 에니메이션 xml 예제

 

<set android:shareInterpolator="false">
   <scale
          android:interpolator="@android:anim/accelerate_decelerate_interpolator"
          android:fromXScale="1.0"
          android:toXScale="1.4"
          android:fromYScale="1.0"
          android:toYScale="0.6"
          android:pivotX="50%"
          android:pivotY="50%"
          android:fillAfter="false"
          android:duration="700" />
   <set android:interpolator="@android:anim/decelerate_interpolator">
      <scale
             android:fromXScale="1.4" 
             android:toXScale="0.0"
             android:fromYScale="0.6"
             android:toYScale="0.0" 
             android:pivotX="50%" 
             android:pivotY="50%" 
             android:startOffset="700"
             android:duration="400" 
             android:fillBefore="false" />
      <rotate 
             android:fromDegrees="0" 
             android:toDegrees="-45"
             android:toYScale="0.0" 
             android:pivotX="50%" 
             android:pivotY="50%"
             android:startOffset="700"
             android:duration="400" />
   </set>
</set>
참조 : interpolator 관련포스트


2. 코드로 에니메이션 구현

코드상에서는 AnimationSet 객체를 선언해 기본 설정을 하고,

각 에니메이션에 해당하는 객체를 설정해 addAnimation() 을 하면 해당 순서대로 에니메이션이 설정된다.


AnimationSet set = new AnimationSet( true );

set.setInterpolator( new AccelerateInterpolator() );


// 각 에니메이션별로 클래스가 존재한다. 페이드인의 경우 AlphaAnimation()

Animation animation = new AlphaAnimation( 0.0f, 1.0f );

animation.setDuration(100);

set.addAnimation(animation);

.

.

.

// xml 과 동일하게.. 하나의 에니메이션은 Animation 객체만 생성하면 되나

// 여러개의 에니메이션은 AnimationSet 객체에 연결한다.


// 레이아웃이나 에니메이션셋의 경우 컨트롤러가 필요하다. 단일한 뷰에니메이션은 필요없음.

LayoutAnimationController controller = new LayoutAnimationController( set, 0.25f );


3. 코드에서 XML 에니메이션 부르기

xml에 정의한 에니메이션 정보를 설정하려면 AnimationUtils 객체를 사용해 해당 에니메이션에 바로 설정할 수 있다.

 

일단... 에니메이션이 두가지가 있는데..

레이아웃이 구성되고 화면에 보일때 레이아웃과 각 차일드에 대한 에니메이션을 설정하는것과

수행 중 뷰들의 에니메이션을 설정하는 것.

 

- 초기 레이아웃의 에니메이션 설정:

LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation( context, R.anim.ani_name);


- 단일 뷰 에니메이션: 머 별 다를게 읍다~(레이아웃이건 뷰건 모두~)

Animation animation = AnimationUtils.loadAnimation( context, R.anim.ani_name );


4. 에니메이션 보이기

어찌되었건 에니메이션이 설정되었으면 해당 에니메이션을 동작시켜야 한다.

역시나 레이아웃과 뷰의 에니메이션 별로 메쏘드가 존재한다.


ViewGroup.setLayoutAnimation( controller ); 

View.startAnimation( animation );


메쏘드명에서 처럼 뷰그룹을 에니메이션 하느냐, 단일 뷰를 에니메이션

하느냐의 차이이다.

액티비티가 로드되어 레이아웃이 화면에 보일때는 각각의 요소에 대해 에니메이션을 지정할 수 없다.

이와 같은경우 ViewGroup 의 레이아웃 에니메이션을 사용하고,

일반적인 경우 아래의 startAnimation을 사용하면 된다.

 


5. AnimationListener

에니메이션관련 이벤트를 수신하기 위해 setAnimationListener() 를 통해

리스너를 등록할 수 있다.

수신할 수 있는 이벤트는 에니메이션 종료, 반복,시작에 해당하는 이벤트이다.

일반적인 리스너처럼 익명 클래스로~


Animation ani = new AlphaAnimation( 0.0f, 1.0f );

ani.setAnimationListener( new AnimationListener() {

@Override

public void onAnimationEnd(Animation arg0) {

}


@Override

public void onAnimationRepeat(Animation arg0) {

}


@Override

public void onAnimationStart(Animation arg0) {

}

});

 


 



* 프레임 에니메이션


drawable 객체를 매 프레임단위로 변경해 에니메이션 효과를 나타내는 방식이다.

<animation-list> 태그를 사용해 구현되며, 각 항목을 <item> 태그로 정의하면 된다.


1. 레이아웃 구현


ex) simple_animation.xml

<?xml version="1.0" encoding="utf-8"?>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

android:oneshot="false">

<item android:drawable="@drawable/image1"

android:duration="50" />

<item android:drawable="@drawable/image2"

android:duration="50" />

</animation-list>


메인 레이아웃에 프레임 에니메이션이 표시될 ImageView를 하나 설정한다.

main.xml


<ImageView android:id=@+id/simple_ani"

android:layout_width="wrap_content"

android:layout_height="wrap_contnet"

android:gravity="center"

android:layout_centerHorizontal="true"

/>


2. 소스 구현


// 우선 이미지뷰를 얻어온다.

ImageView img = (ImageView) findViewById(R.id.simple_ani );


// 해당이미지 뷰의 배경을 에니메이션으로 지정

img.setBackground( R.anim.simple_animation );


에니메이션은 별도의 쓰레드로 구동되어야 하므로, 쓰레드나 TimerTask 혹은

리스너를 통한 콜백을 사용해 에니메이션을 동작시켜 준다.


ex) 타이머를 사용한 구현


MyAnimationTask task = new MyAnimationTask();

Timer t = new Timer(false);

t.schedule( task, 100 );



class MyAnimationTask extends TimerTask

{

public void run() {

ImageView img = (ImageView) findViewById( R.id.simple_ani );

AnimationDrawable frameAni = (AnimationDrawable) img.getBackground();

frameAni.start();

}

};


이처럼 별도의 쓰레드 클래스를 구성하고, 해당 쓰레드에서

AnimationDrawable 객체를 설정해주고 start() 메쏘드를 호출하면 된다.


중지의 경우도 별도의 태스크를 구동시켜 현재 재생중인 에니메이션을 가져온뒤

stop() 메쏘드를 호출해준다.

public void run() {

ImageView img = (ImageView) findViewById( R.id.simple_ani );

AnimationDrawable frameAni = (AnimationDrawable) img.getBackground();

frameAni.stop();

}

'안드로이드' 카테고리의 다른 글

텍스트 마퀴 효과  (0) 2011.10.19
Animation 에서의 interpolator  (0) 2011.10.13
뷰에서 프레임워크가 호출하는 다른 메소드들  (0) 2011.10.12
Criteria  (0) 2011.10.11
메모리 릭 관찰하기  (0) 2011.10.10

+ Recent posts