2012. 9. 24. 16:03
1. 트윈 애니메이션의 종류 및 설명
트윈 애니메이션은 주어진 정보를 이용하여 뷰의 출력 영역을 연산하는 방법을 사용하며 이러한
방법으로 이동, 회전, 투명화, 크기 변경을 구현할 수 있습니다. 하지만 뷰의 출력에 대한 부분만
연산하여 출력시키기 때문에 뷰가 화면에 보이지 않더라도 지속적으로 터치 이벤트를 받는 등
뷰 자체가 애니메이션에 영향을 받지 않으므로 추가적인 처리를 해야할 수도 있습니다.
1.1 투명화 적용
트윈 애니메이션으로 투명화를 적용하면 화면에서 뷰가 점점 사라지도록 표현할 수 있고, 반대로
보이지 않는 뷰가 점점 나타나도록 표현할 수도 있습니다. XML 에서 투명화를 표현할 때 사용하는
요소 및 속성은 아래와 같습니다.
요소명 - alpha
속성
- android:fromAlpha : 애니메이션 시작시 적용될 투명도입니다. 0.0 으로 설정하면 완전한
투명화가 적용되며 1.0 으로 하면 투명도가 적용되지 않습니다.
- android:toAlpha : 애니메이션 종료시 적용될 투명도입니다. 0.0 으로 설정하면 완전한
투명화가 적용되며 1.0 으로 하면 투명도가 적용되지 않습니다.
투명화 애니메이션은 애니메이션 설정한 시간동안 fromAlpha 속성에 지정한 투명도에서 toAlpha
속성에 지정한 투명도로 뷰를 변형시킵니다.
1.2 크기 변경 ( scale )
크기 변경은 뷰의 크기를 변경하는 것입니다. 시작시 뷰의 크기와 애니메이션이 종료될 때의
크기를 지정할 수 있으며 크기 변경시 뷰의 어느 위치를 기준으로 변경이 되는지도 설정할 수
있습니다.
요소명 - scale
속성
- android:fromXScale : 애니메이션 시작시 뷰의 너비입니다. 1.0 이 온전한 뷰의 크기를
의미하며 1.0 보다 작으면 뷰의 너비가 작아지고, 1.0 보다 크면 뷰의 너비가 커집니다.
- android:toXScale : 애니메이션 종료시 뷰의 너비입니다. 1.0 이 온전한 뷰의 크기를
의미하며 1.0 보다 작으면 뷰의 너비가 작아지고, 1.0 보다 크면 뷰의 너비가 커집니다.
- android:fromYScale : 애니메이션 시작시 뷰의 높이입니다. 1.0 이 온전한 뷰의 크기를
의미하며 1.0 보다 작으면 뷰의 너비가 작아지고, 1.0 보다 크면 뷰의 너비가 커집니다.
- android:toYScale : 애니메이션 종료시 뷰의 높이입니다. 1.0 이 온전한 뷰의 크기를
의미하며 1.0 보다 작으면 뷰의 너비가 작아지고, 1.0 보다 크면 뷰의 너비가 커집니다.
- android:pivotX : 뷰의 크기가 변경될 때 뷰의 위치를 의미합니다. 0% 이면 뷰의 좌측이
고정된 상태로 크기가 변경되며 50% 이면 뷰의 중점을 중심으로 뷰의 크기가 변경
됩니다. 즉, 뷰가 커질 땐 좌우로 함께 커지고, 작아질때에도 좌우로 줄어듭니다.
- android:pivotY : 뷰의 크기가 변경될 때 뷰의 위치를 의미합니다. 0% 이면 뷰의 상단이
고정된 상태로 크기가 변경되며 50% 이면 뷰의 중점을 중심으로 뷰의 크기가 변경
됩니다. 즉, 뷰가 커질 땐 상하로 함께 커지고, 작아질때에도 상하로 줄어듭니다.
1.3 이동 ( translate )
두개의 위치 값을 지정하여 시작 위치에서 이동 종료 위치로 뷰를 이동시킵니다.
요소명 - translate
속성
- android:fromXDelta : 뷰의 X 좌표상 시작 위치입니다. 수치값을 직접 입력하면 픽셀단위의
위치로 판단하여 해당 위치에서 시작하며 퍼센트값을 입력하면 뷰의 너비에서 해당
퍼센트를 연산한 위치에서 시작합니다. 또, 퍼센트 뒤에 p 를 붙이면 뷰를 소유한
부모 객체의 너비에서 퍼센트를 연산한 위치에서 시작하게 됩니다.
- android:toXDelta : 뷰의 X 좌표상 이동 종료 위치입니다. 해당 속성이 가질 수 있는 값은
fromXDelta 와 같습니다.
- android:fromYDelta : 뷰의 Y 좌표상 시작 위치입니다. 해당 속성이 가질 수 있는 값은
fromXDelta 와 같습니다.
- android:toYDelta : 뷰의 Y 좌표상 이동 종료 위치입니다. 해당 속성이 가질 수 있는 값은
<translate
android:fromYDelta="0%"
android:toYDelta="50%"
android:duration="2000"
/>
</set>
} else if(id == R.id.size_btn){
} else if(id == R.id.transparent_btn) {
} else if(id == R.id.move_btn) {
fromXDelta 와 같습니다.
1.4 회전 ( rotate )
애니메이션의 시작 시점과 종료 시점의 뷰의 각도, 위치를 지정하여 뷰를 회전 시킵니다.
요소명 - rotate
속성
- android:fromDegrees : 애니메이션이 시작될 때 뷰에 적용되는 각도입니다.
- android:toDegrees : 애니메이션이 종료될 때 뷰에 적용되는 각도입니다.
- android:pivotX : 회전 애니메이션이 이루어질 X 좌표상의 기준 위치입니다. 이 요소에
수치값을 직접 입력하면 픽셀단위의 위치로 판단하여 해당 위치에서 시작하며
퍼센트값을 입력하면 뷰의 너비에서 해당 퍼센트를 연산한 위치에서 시작합니다.
또, 퍼센트 뒤에 p 를 붙이면 뷰를 소유한 부모 객체의 너비에서 퍼센트를 연산한
위치에서 시작하게 됩니다.
- android:pivoxY : 회전 애니메이션이 이루어질 Y 좌표상의 기준 위치입니다. pivotX 속성과
동일하게 값을 설정할 수 있습니다.
2. set 요소와 부가적인 속성들
XML 형식으로 애니메이션을 정의할 때에는 반드시 set 요소 안에 애니메이션 요소들을 정의해야
합니다. set 요소는 여러개의 애니메이션을 하나로 그룹짓는 역할을 하며 애니메이션의 효과를
정의할 수 있는 interpolator 속성을 포함하고 있습니다. 아래의 코드는 이동 애니메이션을 구성하는
간단한 XML 코드입니다.
<?xml version="1.0" encoding="utf-8"?>
<set
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/bounce_interpolator">
<translate
android:fromYDelta="0%"
android:toYDelta="50%"
android:duration="2000"
/>
</set>
루트의 set 요소에는 어플리케이션에서 레이아웃을 구성할 때처럼 요소와 속성명들을 해석할 수
있도록 네임스페이스를 정의해줍니다. set 요소의 interpolator 속성은 뷰의 이동시 어떤 효과를
부가적으로 표현할지를 정의하는데 set 요소에서 모든 애니메이션에 동일하게 효과를 적용시킬
수도 있습니다. interpolator 속성으로 정의 가능한 값과 효과는 다음과 같습니다.
@android:anim/accelerate_decelerate_interpolator
애니메이션이 점점 빠르게 동작하다가 점점 천천히 동작합니다.
@android:anim/accelerate_interpolator
애니메이션이 점점 빠르게 동작합니다.
@android:anim/anticipate_interpolator
애니메이션이 시작할 때 반대 방향으로 동작을 한 후에 본래의 방향으로 동작합니다.
@android:anim/anticipate_overshoot_interpolator
애니메이션이 시작할 때 반대 방향으로 동작을 한 후에 종료 지점을 지나갔다가 종료 지점으로
돌아옵니다. 예를 들어 왼쪽에서 오른쪽으로 이동하는 애니메이션이 있다면 시작할 때 뷰가
왼쪽으로 조금 움직인 후 오른쪽으로 이동하고, 원래 도착해야할 위치를 지났다가 다시 왼쪽으로
이동합니다.
@android:anim/bounce_interpolator
애니메이션이 종료될 때 튕기면서 스프링 효과를 표현합니다.
@android:anim/cycle_interpolator
애니메이션을 동작한 후에 반대 방향으로 한번 더 동작합니다. 만약 오른쪽으로 50 위치까지
이동하는 애니메이션에 이 효과가 적용되면 오른쪽으로 50 만큼 이동한 후에 왼쪽으로 -50
위치까지 이동하게됩니다.
@android:anim/decelerate_interpolator
애니메이션의 움직임이 점점 느려집니다.
@android:anim/linear_interpolator
특별한 효과 없이 일정하게 애니메이션이 동작합니다.
@android:anim/overshoot_interpolator
애니메이션이 동작할 때 멈춰야할 위치를 지난 후에 다시 돌아옵니다.
set 요소에서는 interpolator 속성과 함께 shareInterpolator 속성을 설정해주어야 합니다.
shareInterpolator 속성는 interpolator 속성에 설정한 효과를 내부의 다른 애니메이션들이 공유하여
사용할 것인지 여부를 설정하는 것입니다. 이 속성값은 기본이 true 이며 true 로 설정하면 set 요소
내의 애니메이션이 interpolator 속성에 설정한 효과로 일괄 적용되며 false 로 설정하면 내부의
애니메이션에서 설정한 interpolator 속성을 따로따로 적용하게 됩니다.
그래서 애니메이션마다 각기 다른 interpolator 속성을 적용하더라도 set 요소에서 shareInterpolator
속성에 true 를 지정하면 각자의 애니메이션에서 설정한 효과가 적용되지 않습니다.
또 애니메이션에 startOffset 속성과 duration 속성을 설정할 수 있는데 startOffset 속성은 지정한
밀리초 시간 후에 애니메이션을 동작하겠다는 것이고, duration 속성은 지정한 밀리초 시간만큼
애니메이션을 동작하겠다는 것입니다. 기본적으로 set 요소 내부에 정의된 애니메이션은 동시에
애니메이션이 수행되기 때문에 애니메이션간에 시간 차를 두고싶을 때 startOffset 속성을 사용하며
duration 속성은 지정하지 않으면 애니메이션이 동작할 수 있는 시간이 설정되지 않는 것이므로
반드시 지정해주어야합니다.
3. 간단한 예제
아래의 코드는 네 종류의 애니메이션을 볼 수 있도록 네개의 버튼을 구성하여 각 버튼을 누를때마다
하단의 뷰가 동작하도록 구성한 것입니다.
// rotation.xml - 회전
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/cycle_interpolator">
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="0%"
android:pivotY="0%"
android:duration="1000"
/>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/cycle_interpolator">
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="0%"
android:pivotY="0%"
android:duration="1000"
/>
</set>
// size.xml - 크기 변경
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/cycle_interpolator">
<scale
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
/>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/cycle_interpolator">
<scale
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
/>
</set>
// transparent.xml - 투명화
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.5"
android:duration="1000"
/>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.5"
android:duration="1000"
/>
</set>
// move.xml - 뷰 이동
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:interpolator="@android:anim/bounce_interpolator"
android:fromYDelta="0%"
android:toYDelta="50%"
android:duration="2000"
/>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:interpolator="@android:anim/bounce_interpolator"
android:fromYDelta="0%"
android:toYDelta="50%"
android:duration="2000"
/>
</set>
// mix.xml - 복합 애니메이션
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="0.5"
android:fromYScale="1.0"
android:toYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.5"
android:duration="2000"
/>
<set android:interpolator="@android:anim/accelerate_interpolator">
<scale
android:fromXScale="0.5"
android:toXScale="0.0"
android:fromYScale="0.5"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000"
android:duration="2000"
/>
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000"
android:duration="2000"
/>
</set>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="0.5"
android:fromYScale="1.0"
android:toYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.5"
android:duration="2000"
/>
<set android:interpolator="@android:anim/accelerate_interpolator">
<scale
android:fromXScale="0.5"
android:toXScale="0.0"
android:fromYScale="0.5"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000"
android:duration="2000"
/>
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2000"
android:duration="2000"
/>
</set>
</set>
// 소스 코드 - 버튼을 클릭하여 OnClickListener 인터페이스의 onClick 메소드가 호출되었을 때
public void onClick(View view)
{
int id = view.getId();
if(id == R.id.rotation_btn) {
{
int id = view.getId();
if(id == R.id.rotation_btn) {
// rotation.xml 에 정의된 애니메이션을 불러온다.
Animation ani = AnimationUtils.loadAnimation(this, R.anim.rotation);
Animation ani = AnimationUtils.loadAnimation(this, R.anim.rotation);
// 애니메이션을 동작시킨다.
m_tween_view.startAnimation(ani);
m_tween_view.startAnimation(ani);
} else if(id == R.id.size_btn){
// size.xml 에 정의된 애니메이션을 불러온다.
Animation ani = AnimationUtils.loadAnimation(this, R.anim.size);
Animation ani = AnimationUtils.loadAnimation(this, R.anim.size);
// 애니메이션을 동작시킨다.
m_tween_view.startAnimation(ani);
m_tween_view.startAnimation(ani);
} else if(id == R.id.transparent_btn) {
// transparent.xml 에 정의된 애니메이션을 불러온다.
Animation ani = AnimationUtils.loadAnimation(this, R.anim.transparent);
Animation ani = AnimationUtils.loadAnimation(this, R.anim.transparent);
// 애니메이션을 동작시킨다.
m_tween_view.startAnimation(ani);
m_tween_view.startAnimation(ani);
} else if(id == R.id.move_btn) {
// move.xml 에 정의된 애니메이션을 불러온다.
Animation ani = AnimationUtils.loadAnimation(this, R.anim.move);
Animation ani = AnimationUtils.loadAnimation(this, R.anim.move);
// 애니메이션을 동작시킨다.
m_tween_view.startAnimation(ani);
m_tween_view.startAnimation(ani);
} else if(id == R.id.mix_btn) {
// mix.xml 에 정의된 애니메이션을 불러온다.
Animation ani = AnimationUtils.loadAnimation(this, R.anim.mix);
Animation ani = AnimationUtils.loadAnimation(this, R.anim.mix);
// 애니메이션을 동작시킨다.
m_tween_view.startAnimation(ani);
}
}
m_tween_view.startAnimation(ani);
}
}
'Mobile > Android' 카테고리의 다른 글
BroadcastReceiver (0) | 2012.11.02 |
---|---|
Push에 대한 것! (0) | 2012.10.30 |
AsyncTask (0) | 2012.09.21 |
Context (0) | 2012.09.21 |
UI쓰레드와 Handler (0) | 2012.09.21 |