Android (안드로이드)

[Android] 애니메이션 효과 / animation / View 움직임, 이동 / 트윈 애니메이션

Oscar:) 2022. 9. 6. 20:49

 

이번 포스팅에서는 View 에 애니메이션 효과를 부여함으로써,

 

앱에 생동감을 불어 넣어주는 작업을 해볼 것이다.

 

 


 

 

안드로이드에서 애니메이션을 적용할 수 있는 방법은 다양하다.

 

  • 비트맵 애니메이션
  • UI 가시성 및 모션 애니메이션
  • 물리학 기반 모션
  • 레이아웃 및 액티비티 변경 애니메이션

등등 공식 문서에서 소개하는 종류만 해도 정말 많다.

 

우리는 그중에서도, 가장 보편적으로 사용할 수 있는

'트윈 애니메이션' 에 대해 알아보겠다.

 

 

 

트윈 애니메이션이란?

 

  • 회전 (rotate)
  • 규모 (scale)
  • 이동 (translate)
  • 투명도 (alpha)

 

위 4가지 방식을 xml 파일로 정의하여 View 에 적용하는 애니메이션 방식이다.

 

구현이 간단하기 때문에, 초보자들도 쉽게 사용할 수 있다.

 

 

 

애니메이션 디렉토리 및 파일 생성

 

위에서도 언급했듯이, xml 파일로 정의되기 때문에

리소스 파일을 생성해줘야 한다.

 

프로젝트의 하위 폴더 중, res 폴더에 'anim' 이라는 이름으로

하위 폴더를 생성해준다.

 

'anim' 이라는 이름으로 폴더를 생성했다면,

프로그램이 애니메이션 전용 폴더로 인식한다.

 

따라서, 해당 'anim' 폴더를 우클릭하면

'애니메이션 리소스 파일 생성' 탭을 확인할 수 있다.

 

초기 설정 값은 set 으로 되어있을 텐데, 신경 쓰지 말고 그대로 생성해 주면 된다.

 

 

보통의 경우, 애니메이션 효과를 적용한다면

위에서 언급한 4가지 속성 중에서 1개만 선택하여 사용하는 경우는 드물다.

 

최소 2개 이상을 혼합해서 사용할 것이다.

 

그리고 그 경우에는 set 태그를 사용한다.

(1개만 사용한다면, 해당 속성을 태그로 사용하면 된다.)

 

 

 

 

 

java 파일에서 참조하기

 

rotate.xml 이라는 이름을 가진 애니메이션 파일을 생성했다고 가정하겠다.

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

// 1번
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

public class AnimActivity extends AppCompatActivity {

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

// 2번
        ImageView android = findViewById(R.id.android);
        Button button = findViewById(R.id.Button);
        
// 3번
        Animation rotate = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.rotate);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            
// 4번
                android.startAnimation(rotate);
            }
        });

    }
}

 

번잡해 보이지만, 유심히 봐야될 곳은 몇 군데 없다.

 

1. android.view.animation.Animation / AnimationUtils  >  import 해준다.

2. 애니메이션 효과를 적용할 View 와 동작시킬 View 생성해준다.

3. Animation 객체 참조하기
AnimationUtils.loadAnimation() 메서드를 사용하며,
매개변수로는 Context와 애니메이션 xml 파일을 작성해준다.

4. 이벤트 발생 시, 해당 View 에 애니메이션을 적용해준다.
startAnimation() 메서드를 사용하며, Animation 객체를 넣어준다.

 

 

해당 액티비티의 레이아웃 파일은 따로 게시하지 않을테니,

애니메이션이 적용될 View 와, 작동시킬 Button 의 경우는

알아서 커스텀하여 적용해보길 바란다.

 

 

 

폴더 생성, 파일 생성, java 참조까지 큰 틀은 모두 알아보았다.

 

이제 애니메이션을 만들어보자.

 

 

 

트윈 애니메이션 종류 및 특징

 

 

위에서 언급한 4가지 종류가 있으며,

각 속성마다 적용할 수 있는 요소가 존재한다.

 

from - to / X - Y 등의 맥락은 비슷하기 때문에 이해가 어렵진 않을 것이다.

 

 

● 회전 (rotate)

 

 

해당 코드는 다음과 같다.

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:duration="2000"
        />
</set>

(아래에서 따로 추가 설명하겠지만, duration 은 지속 시간이다)

 

속성의 각 요소 의미는 다음과 같다.

 

- pivotX : X축의 중심점

- pivotY : Y축의 중심점

- fromDegrees : 시작 지점의 각도

- toDegrees :  도착 지점의 각도

 

 

pivot이 50% 로 지정되었기에, View 의 정가운데를 중심으로 회전한다.

fromDegrees=0 > toDegrees=360 : 1바퀴 회전한다.
+ toDegrees=720 으로 지정한다면 2바퀴 회전한다.
+ from 과 to 의 수치를 바꾸면 반대 방향으로 회전한다.

 

 

 


 

● 규모 (scale)

 

 

해당 코드는 다음과 같다.

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="100%"
        android:fromYScale="100%"
        android:toXScale="200%"
        android:toYScale="200%"
        android:duration="2000"
        />
</set>

 

속성의 각 요소 의미는 다음과 같다.

 

- pivotX : X축의 중심점

- pivotY : Y축의 중심점

- fromXScale : 시작 지점의 X축 규모

- fromYScale : 시작 지점의 Y축 규모

- toXScale : 도착 지점의 X축 규모

- toYScale : 도착 지점의 Y축 규모

 

 

pivot이 50% 로 지정되었기에, View 의 정가운데를 중심으로 확대된다.

fromScale=100% 은 본래의 크기, toScale=200% 은 본래 크기의 2배를 뜻한다.
따라서 본래 크기의 2배 만큼 확대되었다.

 

 

 


 

● 이동 (translate)

 

 

해당 코드는 다음과 같다.

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="50%"
        android:toYDelta="50%"
        android:duration="2000"
        />
</set>

 

속성의 각 요소 의미는 다음과 같다.

 

- fromXDelta : X축의 시작 지점

- fromYDelta : Y축의 시작 지점

- toXDelta : X축의 도착 지점

- toYDelta : Y축의 도착 지점

 

fromDelta=0 > toDelta=50% 로 지정하였기 때문에,
해당 View 크기의 X축, Y축 각각의 절반만큼 이동하였다.

반대 방향으로 이동하고 싶을 때는, - (음수) 를 사용한다.

 

 

 


● 투명도 (alpha)

 

 

해당 코드는 다음과 같다.

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1.0"
        android:duration="2000"
        />
</set>

 

속성의 각 요소 의미는 다음과 같다.

 

- fromAlpha : 시작 지점의 투명도

- toAlpha : 도착 지점의 투명도

 

fromAlpha=0 > toAlpha=1.0 으로 지정하였기 때문에
아예 안 보였다가, 본래의 투명도로 나타났다.

위 3가지 속성과는 다르게, %(퍼센트) 적용이 안 된다.
따라서, 0.0 ~ 1.0 으로 조절해주길 바란다.

 

 

 

 

 

공통 요소

 

각 속성마다 적용되는 특별 요소가 아닌, 공통되는 요소가 있다.

 

 

- duration : 지속 시간

 

애니메이션이 지속되는 시간이다.

'1000' = 1초 단위이다.

(위 예제에서는 모두 '2000' 으로 작성하였기 때문에 2초 지속이다)

 

default 값이 0이기 때문에, 반드시 작성해 주어야 한다.

(작성해 주지 않는다면 재생되지 않는다)

 

자동 완성 기능이 기본 적용되어 있지 않아서 불편한 감이 있다.

 


 

- repeatCount : 반복 횟수

 

지정된 지속 시간이 끝나고, 추가적으로 반복시킬 수 있다.

default 값은 0이다. (작성해 주지 않는다면 1번 재생 후 정지)

 

무한 반복시킨다면 'infinite' 를 작성해준다.

 


 

- startOffset : 시작 대기 시간

 

말 그대로, 애니메이션이 시작되기 전에 대기하는 시간이다.

'1000' 값을 작성하면 해당 애니메이션이 1초 뒤에 시작한다.

 

여러 애니메이션을 혼합하여 사용할 때, 주로 사용한다.

 


 

- interpolator : 보간기

'수치제어 기계에 있어서, 복잡한 곡선의 근사가공을 할 때 사용'

*interpolate : 보간

 

의미는 다소 어렵게 들리지만, 쉽게 이해하자면

애니메이션에 추가적인 효과를 주는 속성이라고 생각하면 된다.

 

 

아래 문법을 사용하며, 가장 상위 태그에 작성해주어야 적용이 된다.

android:interpolator="@android:anim/해당 보간"

 

 

interpolator 의 종류 또한 다양하며, 필요하다면 적용해보길 바란다.

아래 예시는 rotate 애니메이션을 기준으로 적용하였다.

 

  • linear_interpolator

 

변화 속도가 일정하다. (default 값이다)


  • accelerate_interpolator

 

처음에 느리다가 점점 빨라진다.


  • decelerate_interpolator

 

처음에 빠르다가 점점 느려진다.


  • anticipate_interpolator

 

살짝 되감기 후 진행한다.


  • overshoot_interpolator

 

끝나는 부분을 초과하여 진행했다가 되돌아온다.


  • bounce_interpolator

 

끝나는 부분에서 바운스한다.


  • cycle_interpolator

 

끝까지 갔다가 처음으로 되돌아오기를 몇 차례 반복한다.

 

 

 

 

 

혼합 사용 예시

 

위에서 배웠던 여러 애니메이션 속성을 혼합하여 사용해 보았다.

 

 

해당 코드는 다음과 같다.

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

    <rotate
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:duration="1000"
        />

    <alpha
        android:fromAlpha="0"
        android:toAlpha="1.0"
        android:duration="1000"
        />

    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="100%"
        android:fromYScale="100%"
        android:toXScale="150%"
        android:toYScale="150%"
        android:startOffset="1000"
        android:duration="500"
        />

    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale="100%"
        android:fromYScale="100%"
        android:toXScale="68%"
        android:toYScale="68%"
        android:startOffset="1500"
        android:duration="500"
        />

</set>

 

간단히 설명을 덧붙이자면,

 

- rotate : 1초동안 1바퀴 회전
- alpha : 안보였다가 1초동안 모습을 나타냄

위 2가지는 동시에 이루어진다.

 

 

첫 번째 scale : 0.5초 동안 1.5배 확대

startOffset='1000' 옵션이 있기 때문에, 1초 후에 시작된다.

 

 

두 번째 scale : 0.5초 동안 본래 사이즈로 축소

68% 는 시각적으로 맞춘 수치이다.

첫 번째 scale 에서 150% 확대해놓은 수치가,

두 번째 scale 에서는 100% 로 적용되기 때문이다.

 

startOffset='1500' 옵션이 있기 때문에, 1.5초 후에 시작된다.

 

 

위처럼, startOffset 속성으로 여러 애니메이션을 자연스럽게 혼합할 수 있다.

 

 


 

 

 

이번 포스팅에서는 안드로이드의 트윈 애니메이션에 대해 알아보았다.

 

UI 요소가 움직이다보니, 확실히 앱이 살아나는 느낌을 받는다.

 

앱을 보강하거나, 마무리할 때 추가해주면 좋을 것 같다.