트윈 애니메이션(Twin Animation) : 이동(Translate) / 확대&축소(Scale)🔎 / 회전(Rotate) / 투명도(Alpha)👻

                                                        위와  같이 일정한 패턴으로 움직이는 애니메이션을 구현할 때 사용됨.

                                                        대상은 (위젯이나 레이아웃), 그리기 객체(Drawable)이다.

 

[ 애니메이션의 동작 ]

  1. XML로 애니메이션의 동작을 정의한다.
  2. JAVA 소스에서 애니메이션 객체로 로딩한다.
  3. 뷰 객체의 startAnimation 메서드로 애니메이션이 동작한다.

 

[ 애니메이션 파일 디렉토리 ]

애니메이션을 위한 XML 파일은 app/res/anim 폴더에 들어가야 한다.

anim 폴더를 생성한 뒤 새 파일을 추가하려고 하면 Animation Resource File을 생성할 수 있다.

 

 

🚩확대&축소 애니메이션

1️⃣scale.xml 파일을 생성했다.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale
        android:duration="2500"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="2.0"
        android:toYScale="2.0"
        />
</set>
  • startOffset : 시작 시간
  • duration : 지속 시간(msec)
  • pivotX / pivotY : 크기를 변경하려는 축의 정보
  • fromXScale / fromYScale : 시작할 때의 확대/축소 비율
  • toXScale / toYScale : 끝날 때의 확대/축소 비율

위 코드의 경우, 2.5초간 애니메이션이 동작함. 1.0배에서 2.0배로, 원래 크기보다 2배 커지는 애니메이션이다.

 

2️⃣activity_main.xml은 간단하게 버튼을 하나 추가해주었다.

3️⃣MainActivity.java

버튼에 setOnClickListener를 설정한 뒤, onClick 메서드에 아래 코드를 작성했다.

Animation anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.scale);
view.startAnimation(anim);

 

[전체 코드]

더보기
package com.example.chapter8_1;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Animation anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.scale);
                view.startAnimation(anim);
            }
        });
    }
}

[에러 발생(SDK 버전 문제)]

더보기

왜 이 예제를 실행할 때 이 에러가 나는지 잘 모르겠다. 더 높은 버전의 SDK를 사용하라는데 애니메이션을 사용하려면 그래야 하는것인가? 아무튼 SDK34 -> SDK35로 바꿔주었더니 해결되었다.

4️⃣ 실행 결과

천천히 확대 후에, 바로 원래의 크기로 돌아간다. (천천히 축소되지 않는다.)

애니메이션으로 크기가 바뀐 뒤 고정되지 않는다.

 

5️⃣ 수정 후 실행 결과

위 코드에 확대 애니메이션만 있어서 축소가 부자연스럽다. 그래서 축소 애니메이션을 추가했다.

[수정된 scale.xml]

더보기
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale
        android:duration="2500"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="2.0"
        android:toYScale="2.0"
        />

    <scale
        android:startOffset="2500"
        android:duration="2500"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="0.5"
        android:toYScale="0.5"
        />
</set>

시작시간 startOffset이 추가되었다. 확대 애니메이션이 2.5초간 이루어지므로, 축소 애니메이션은 2.5초부터 시작되게끔 설정해주었다.

 

1.0배 - >0.5배로 줄어드므로, 2배 축소되는 것이다.

확대 애니메이션에서 2배 확대되었으니 2배 축소면 다시 원래 크기로 돌아가는 것이다.

부드럽게 확대되고, 부드럽게 축소된다.

 

 

🚩이동 애니메이션

새로운 move.xml을 만들어주겠다. <translate> 태그를 사용하여 정의한다. (가장 바깥이 set 태그여도 무방하긴 함)

1️⃣ 반복되는 이동 애니메이션

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

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%"
    android:toXDelta="-200%"
    android:duration="5000"
    android:repeatCount="-1"
     />

repeatCount="-1"로 설정하면 애니메이션이 무한 반복된다. 버튼이 5초 간 왼쪽으로 이동한 다음 다시 원래 위치에서 애니메이션을 반복한다.

 

2️⃣ 애니메이션 후 변경사항 고정시키기

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

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%"
    android:toXDelta="-200%"
    android:duration="5000"
    android:fillAfter="true"
     />

fillAfter="true"로 설정하면 애니메이션이 끝난 후에도 초기 상태로 되돌아가지 않는다.

(이외에도 fillEnable이라는 속성이 있기는 했는데.. 많이 사용하지는 않는 듯 하다.)

 

 

🚩회전 애니메이션

rotate.xml을 만들어주겠다. <rotate> 태그를 사용한다.  (가장 바깥이 set 태그여도 무방하긴 함)

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="10000"
/>

10초간 0도 -> 360도 즉 한 바퀴를 돈다. (0->-360도로 설정했으면 반시계 방향으로 돌아간다. 사실 뇌피셜임 동작안해봄)

 

 

🚩투명도 애니메이션

alpha.xml을 만들어준다. <alpha> 태그를 사용한다.

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="10000"
    />

10초간 투명도 0.0(0%)에서 1.0(100%)로 바뀌는 애니메이션이다.

 

버튼을 누르면 투명도가 0이 되고, 서서히 선명해지다가 초기 상태만큼 선명해진다.

 

 

🚩인터폴레이터 : 속도 조절하기

인터폴레이터(Interpolator)를 사용하여 애니메이션 효과가 지속되는 속도를 조절할 수 있다.

  • accelerate_interpolator : 점점 빠르게🐇
  • decelerate_interpolator : 점점 느리게🐢
  • accelerate_decelerate_interpolator : 점점 빠르다가 느리게🐇🐢
  • anticipate_interpolator : 시작 위치에서 조금 뒤로 당겼다가 시작🔙➡
  • overshoot_interpolator : 종료 위치에서 조금 지나쳤다가 종료⏩
  • anticipate_overshoot_interpolator : 시작 위치에서 조금 뒤로 당겼다가 시작한 후 종료 위치에서 조금 지나쳤다가 종료
  • bounce_interpolator : 종료 위치에서 튀도록🏀

이런 정보들은 각각의 액션, 또는 애니메이션 집합에 설정할 수 있다.

(각각의 액션에 다른 인터폴레이션을 설정하는 경우 shareInterpolator="false"로 설정해준다.)

 

애니메이션 정보들은 자바 코드에서 new 연산자로 직접 만들 수도 있다.

(TranslateAnimation / RotateAnimation / ScaleAnimation / AlphaAnimation / AnimationSet(애니메이션 집합))

 

 

🚩사용자에게 화면이 표시되는 시점에 애니메이션이 시작하도록 하기

애니메이션의 시작점 : onWindowFocusChanged 메서드가 호출되는 시점(=윈도우가 포커스를 받는 시점)

onWindowFocusChanged 메서드 내에서 파라미터로 전달되는 hasFocus="true"일 경우 각각의 애니메이션 객체에 대해 start 메서드를 호출함으로써 애니메이션이 시작되도록 한다. (뭐라는지 알것같기도하고.. 예제 왜 없어)

 

윈도우가 다른 윈도우에 의해 가려지거나 할 때는 hasFocus="false"가 된다.

  • onAnimationStart : 애니메이션이 시작되기 전에 호출됨
  • onAnimationEnd : 애니메이션이 끝났을 때 호출됨
  • onAnimationRepeat : 애니메이션이 반복될 때 호출됨

 

 

⭐애니메이션 속성 총정리⭐

  • startOffset : 시작 시간(msec)
  • duration : 지속 시간(msec)
  • repeatCount : 반복횟수 (-1을 넣으면 무한반복)
  • fillAfter : 애니메이션 후 변경사항 유지(true/false)
  • 🌟확대/축소
  • pivotX / pivotY : 크기를 변경하려는 축의 정보 (%)
  • fromXScale / fromYScale : 시작할 때의 확대/축소 비율 (X.X)
  • toXScale / toYScale : 끝날 때의 확대/축소 비율 (X.X)
  • 🌟이동
  • fromXDelta / fromYDelta / toXDelta / toYDelta : 이동하는 정도 (%) (0% : 그대로, 100% : x축 또는 y축으로 자기 자신만큼 + 방향으로 이동. -100% : x축 또는 y축으로 자기 자신만큼 - 방향으로 이동.)
  • 🌟회전
  • fromDegrees / toDegrees : 시작 각도에서 종료 각도만큼 회전.
  • 🌟투명도
  • fromAlpha / toAlpha : 투명한 정도 (0:투명, 1:불투명)