정말 오랜만입니다
글쓰는거 참 어렵습니다;
이번에는 아주 간단한 애니메이션에 대해 알아보겠습니다
30. 애니메이션에 대해 알아보자 (Tween Animation)
30-1 애니메이션?
이 강좌에서 알려드릴 애니메이션은 Tween Animation이라는 이름을 가진 애니메이션 입니다
트윈 애니메이션 이라고 하는데요
버튼이 움직이거나, 사라지거나, 위치가 바뀌거나, 커지거나
이런 효과를 띄울수 있습니다
사용되는 속성이 적지 않고 이해하기 어려운 부분이 많습니다
다음 강좌가 올라올때까지 예제소스를 숨겨두지 말고 바로 오픈하고 있으니 글 한번 보시고 바로 소스를 보시는걸 추천드립니다
참고로 이 트윈 애니메이션은 간단한 애니메이션입니다;
나중에는 그래프 애니메이션등등등... 머리아파요 ㅠㅠ
30-2 메인 레이아웃 투척
30대 강좌에서 레이아웃을 공부하는것은 무의미 하므로 투척합니다
메인 레이아웃에는 버튼 5개를 만들어 주시면 됩니다
이 강좌에서 배울 애니메이션은 4가지이고, Set이라는건 두가지 이상의 효과를 동시에 사용할때 사용합니다
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.exampletweenanimation.MainActivity$PlaceholderFragment" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:onClick="alpha"
android:text="Alpha" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:onClick="rotate"
android:text="Rotate" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:onClick="scale"
android:text="Scale" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:onClick="translate"
android:text="Translate" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:onClick="set"
android:text="Set" />
</LinearLayout>
30-3 res/anim
애니메이션을 정의한 xml파일은 res/anim폴더에 들어있습니다
[Development/App] - #3 App의 구조와 동작 원리 강좌에서 res폴더 내부를 관찰할때 설명했던 부분입니다
혹시 까먹으신분 있으실까봐...
기본적으로 프로젝트를 만들면 이 폴더는 없습니다
따로 만들어 주시면 됩니다
res/anim에는 5가지의 xml 파일을 만들꺼예요
먼저 투명도를 조절하는 alpha부터 관찰해 봅시다
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="10000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
정말 간단합니다
저 <alpha> 태그에 정의된 대로 애니메이션이 표시될 겁니다
먼저, 어떤 속성들이 존재하는지 확인해 보겠습니다
- android:duration : 지속시간 입니다, 1000이 1초이며, x초동안 애니메이션을 재생하라 라는 뜻입니다
- android:fromAlpha : 처음 투명도 값입니다, 0.0부터 1.0까지의 범위이며, 0.0이 완전투명이고, 1.0이 불투명 입니다
- android:toAlpha : 끝날때 투명도 값입니다
종합해 보면, 10초동안 처음에 완전 투명에서 불투명으로 투명도를 바꿔라 라는 뜻입니다
<alpha>에서 3개의 속성만 사용할수 있을까요?
그건 아닙니다
아래에 공통적으로 쓰이는 몇가지 속성을 입력해 두겠습니다
- android:startOffset : 애니메이션을 시작하기 전 대기시간 입니다
- android:repeatCount : 반복 횟수 입니다 -1은 무한반복
- android:repeatMode (restart, reverse) : 반복 모드입니다 restart는 애니메이션을 처음부터 반복, reverse는 애니메이션을 반시계방향으로 다시 실행
- android:interpolator : 애니메이션 효과가 지속되는 동안 빠르게, 또는 느리게 효과가 진행되도록 만듭니다
- android:fillAfter : 애니메이션 효과가 끝난뒤에 상태를 유지할지 결정합니다, 기본은 false
이중 android:interpolator에 들어가는 속성에 대해 자세한 설명을 더보기 처리 해두었습니다
linear_interpolator : 일정하게 진행이 된다
accelerate_interpolator : 점점 속도를 더해가며 빠르게 진행한다
decelerate_interpolator : 점점 느리게 진행한다
accelerate_decelerate_interpolator : accelerate/decelerate 동시적용 된다.
anticipate_interpolator : 시작위치에서 조금 뒤로 이동햇다가 이동
overshoot_interpolator : 도착위치를 조금 지나쳣다가 도착위치로 이동
anticipate_overshoot_interpolator : anticipate/ overshoot 동시적용 된다.
bounce_interpolator : 도착위치에서 팅기는 효과를 준다.
cycle_interpolator : 애니메이션을 반복한다.
애니메이션 집합인 <set>에 정의합니다
android:shareInterpolator="false" : 하위 애니메이션에 각각 다른 interpolator를 적용할때 씁니다
다음은 회전을 담당하는 rotate입니다
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="10000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
여기서도 처음 보는 속성들이 몇개 보입니다
- android:fromDegrees : 시작하는 회전각도
- android:toDegrees : 끝의 회전각도
- android:pivotX : 회전축의 X 좌표
- android:pivotY : 회전축의 Y 좌표
이부분이 좀 이해하기 어렵습니다...
android:fromDegrees와 android:toDegrees는 직접 값을 변경해 보시면서 알아가시는게 확실히 와닿습니다
아래 두개의 설명을 더 자세하게 드리면
View가 회전할때 회전의 중심이 되는 중심 축을 설정합니다
이때 단위를 "정수", "%", "%p"를 사용할수 있는데요
정수의 경우는 절대 좌표이고, %는 애니메이션을 적용할 View를 기준으로 한 비율, %p는 View를 감싸는 부모 View를 기준으로 한 비율입니다
이해가 안됩니다...
제가 이해한것이 맞다면 이렇게 표현될것입니다
50%, 50%는 딱 중간이겠지요?
즉 중간을 기준으로 0도부터 360도 까지 회전한다 라는 뜻입니다
3번째로 크기를 담당하는 Scale입니다
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="2.0"
android:toYScale="2.0" />
으어어어어어어어어
머리아프네요
- android:fromXScale="1.0" : 처음의 가로 크기입니다 1.0은 원래 크기이고요
- android:fromYScale="1.0" : 처음의 세로 크기입니다
- android:pivotX="50%" : 크기를 변경할때의 중심점 입니다 X좌표이고, 설명은 위와 같습니다
- android:pivotY="50%" : Y좌표이고, 위와 같습니다
- android:toXScale="2.0" : 끝의 가로 크기입니다 2.0은 1.0의 두배이므로 두배로 크기를 키우는 애니메이션을 볼수 있습니다
- android:toYScale="2.0" : 끝의 세로 크기입니다, 위와 같습니다
다음은 위치변경 입니다
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fillAfter="true"
android:fromXDelta="0%p"
android:fromYDelta="0%p"
android:toXDelta="20%p"
android:toYDelta="20%p" />
- android:fromXDelta="0%p" : 처음 애니메이션이 시작될때 View의 X 위치입니다 0%p이므로 원래 위치
- android:fromYDelta="0%p" : 처음 애니메이션이 시작될때 View의 Y 위치입니다 0%p이므로 원래 위치
- android:toXDelta="20%p" : 끝날때 X위치입니다 가로이므로 부모 View의 20%만큼 오른쪽으로 이동합니다
- android:toYDelta="20%p" : 끝날때 Y위치입니다 세로이므로 부모 View의 20%만큼 아래로 이동합니다
이제 마지막으로 애니메이션을 묶을수 있는 Set에 대해 알아봅시다
이건... 그냥 <set> </set>으로 여러 애니메이션들을 묶어주시면 됩니다 ㅋㅋㅋ
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="5000"
android:fromAlpha="0.4"
android:toAlpha="1.0" />
<scale
android:duration="5000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="2.0"
android:toYScale="2.0" />
<scale
android:duration="5000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="2500"
android:toXScale="0.5"
android:toYScale="0.5" />
<rotate
android:duration="5000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
</set>
작동 영상을 확인해 보겠습니다
간단하다고 했지만 설명하면 이게 뭔말인지 모르실겁니다
저도 아직 완벽하게 이해한부분이 아니므로 틀린부분이 있을수 있습니다
많은 지적 부탁드립니다
java로 애니메이션을 만드는 방법은 자세한 글이 있어 소개해 드립니다
http://blog.naver.com/jolangma/150115948509
현재 안드로이드에서 지원해주고 있는 tween animation 관련 class는 아래와 같습니다.
// 투명도 관련 클래스
// 0.0(완전투명) ~ 1.0(완전불투명) 의 값이 사용됩니다.
AlphaAnimation ani = new AlphaAnimation(float fromAlpha, float toAlpha);
view.startAnimation(ani);
// 확대/축소 관련 클래스
ScaleAnimation ani =
// 0.0 ~ 1.0(원래 크기) 의 값이 사용됩니다.
new ScaleAnimation (float fromX, float toX, float fromY, float toY) ;
// 중심점은 animation되는 이미지의 절대 좌표를 사용합니다.
// x = 0 이면 left edge, y = 0이면 top edge 를 가리킵니다.
new ScaleAnimation (float fromX, float toX, float fromY, float toY, float pivotX, float pivotY);
// Type에 사용되는 것은 아래와 같습니다.
// Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT
// Value에는 Type이 absolute일 때 scale되는 이미지의 절대 좌표이가 사용되고
// 나머지 Type에서는 0.0(0%) ~ 1.0(100%)의 값을 사용하는 퍼센트를 사용합니다.
new ScaleAnimation (float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) ;
view.startAnimation(ani);
// 이동(위치) 관련 클래스
TranslateAnimation ani =
// 절대 좌표를 사용합니다.
new TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);
// Type에 사용되는 것은 아래와 같습니다.
// Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT
// Value에는 Type이 absolute일 때 scale되는 이미지의 절대 좌표이가 사용되고
// 나머지 Type에서는 0.0(0%) ~ 1.0(100%)의 값을 사용하는 퍼센트를 사용합니다.
new TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue);
view.startAnimation(ani);
// 회전 관련 클래스
RotateAnimation ani =
// 기본 중심점은 (0, 0) 입니다.
new RotateAnimation (float fromDegrees, float toDegrees);
// 중심점은 animation되는 이미지의 절대 좌표를 사용합니다.
// x = 0 이면 left edge, y = 0이면 top edge 를 가리킵니다.
new RotateAnimation (float fromDegrees, float toDegrees, float pivotX, float pivotY);
// Type에 사용되는 것은 아래와 같습니다.
// Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT
// Value에는 Type이 absolute일 때 scale되는 이미지의 절대 좌표이가 사용되고
// 나머지 Type에서는 0.0(0%) ~ 1.0(100%)의 값을 사용하는 퍼센트를 사용합니다.
new RotateAnimation (float fromDegrees, float toDegrees,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
view.startAnimation(ani);
그리고 위의 애니메이션 중 하나 이상의 애니메이션을 함께 적용하고자 할 때 사용하는 클래스입니다.
// Interpolator(보간기) : 복잡한 곡선의 근사가공
// true : AnimationSet의 보간기 사용, false : set에 추가된 각 Animation의 보간기 사용
AnimationSet ani = new AnimationSet(boolean shareInterpolator);
aniSet.addAnimation(aniTranslate);
aniSet.addAnimation(aniScale);
view.startAnimation(ani);
유용한 리스너를 사용하면 편합니다.
// 애니메이션 리스너를 연결합니다.
ani.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationStart(Animation animation) {
// Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// Auto-generated method stub
}
public void onAnimationRepeat(Animation animation) {
// Auto-generated method stub
}
});
ExampleTweenAnimation.zip
머리가 아파서 횡설수설한거같네요;
예제소스 뜯어보시며 값 하나씩 수정해 보시면 더 정확히 아실수 있을겁니다