toggle menu

애니메이션 구현하기

2012. 6. 20. 15:07 Android

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

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




* 에니메이션

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

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


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

AlphaAnimation - 투명도 변환

RotateAnimation - 회전

ScaleAnimation - 크기 변환

TranslateAnimation - 위치 이동

 

* 이 클래스들은 android.view.animation.Animation 의 하위 클래스이다. 즉, Animation 객체를

상속받아 다양한 에니메이션을 구현할 수 있다.

이번 포스트에서는 이미 구현되어 있는 에니메이션만 언급한다.


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 객체에 연결한다.

 

// 에니메이션 설정

this.setAnimation(set);

 


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

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

 

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

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

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

 

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


4. 에니메이션 보이기

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

animationset, animation 동일하게 아래와 같이 시작시킬수 있다.


View.startAnimation( animation );

 


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) {

}

});

 

6. 레이아웃 에니메이션

뷰에니메이션과 같은 형태로 구성한다. 단, 아래의 에니메이션은 레이아웃 자체의 움직임과는 관계가 없고, 하위 뷰의 추가시 해당 에니메이션이 발생하게 된다.

 

* xml에 구성

res/anim/에니메이션명.xml

 

페이드되면서 나타나는 아이템의 경우 아래와 같이 작성한다.

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

android:delay=""

android:animationOrder="random" // reverse

android:animation="@anim/에니메이션" />

 

해당 레이아웃에니메이션을 적용하고자 하는 레이아웃에 지정.

<ListView

.

android:layoutAnimation="@anim/에니메이션명"

.

./>

 

* 코드에서 구성

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

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

 

에니메이션 지정

ViewGroup.setLayoutAnimation( controller );

 

 

* 프레임 에니메이션


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();

}

Android 관련 포스팅 더보기