드로어블 그래픽 애니메이션 처리

Compose 사용해 보기
Jetpack Compose는 Android를 위한 권장 UI 도구 키트입니다. Compose에서 애니메이션을 사용하는 방법을 알아봅니다.
그림 1. 애니메이션된 드로어블입니다.

이미지를 애니메이션으로 표시해야 하는 경우도 있습니다. 여러 이미지로 구성된 맞춤 로드 애니메이션을 표시하거나 사용자 작업 후에 아이콘이 변형되게 하려는 경우 유용합니다. Android에서는 드로어블 애니메이션을 위한 두 가지 옵션을 제공합니다.

첫 번째 옵션은 AnimationDrawable를 사용하는 것입니다. 이렇게 하면 애니메이션을 만들기 위해 한 번에 하나씩 표시되는 여러 개의 정적 드로어블 파일을 지정할 수 있습니다. 두 번째 옵션은 벡터 드로어블의 속성을 애니메이션화할 수 있는 AnimatedVectorDrawable를 사용하는 것입니다.

AnimationDrawable 사용

애니메이션을 만드는 한 가지 방법은 필름 한 통처럼 일련의 드로어블 리소스를 로드하는 것입니다. AnimationDrawable 클래스는 이러한 종류의 드로어블 애니메이션의 기반입니다.

AnimationDrawable 클래스 API를 사용하여 코드에서 애니메이션의 프레임을 정의할 수 있지만 애니메이션을 구성하는 프레임을 나열하는 단일 XML 파일로 프레임을 정의하는 것이 더 쉽습니다. 이 애니메이션 유형의 XML 파일은 Android 프로젝트의 res/drawable/ 디렉터리에 있습니다. 이 경우 명령어는 애니메이션의 각 프레임의 순서와 지속 기간을 지정합니다.

XML 파일은 루트 노드인 <animation-list> 요소와 각각 프레임(드로어블 리소스 및 지속 시간)을 정의하는 일련의 하위 <item> 노드로 구성됩니다. 다음은 Drawable 애니메이션의 XML 파일 예입니다.

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

이 애니메이션은 3프레임 동안 실행됩니다. 목록의 android:oneshot 속성을 true로 설정하면 한 번 순환한 다음 마지막 프레임에서 정지된 상태로 있습니다. android:oneshotfalse로 설정하면 애니메이션이 반복됩니다.

이 XML을 프로젝트의 res/drawable/ 디렉터리에 rocket_thrust.xml로 저장하면 View에 배경 이미지로 추가한 다음 start()를 호출하여 재생할 수 있습니다. 다음은 애니메이션이 ImageView에 추가된 다음, 화면을 터치하면 애니메이션되는 활동의 예입니다.

Kotlin

private lateinit var rocketAnimation: AnimationDrawable

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val rocketImage = findViewById<ImageView>(R.id.rocket_image).apply {
        setBackgroundResource(R.drawable.rocket_thrust)
        rocketAnimation = background as AnimationDrawable
    }

    rocketImage.setOnClickListener({ rocketAnimation.start() })
}

자바

AnimationDrawable rocketAnimation;

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

  rocketImage.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        rocketAnimation.start();
      }
  });
}

AnimationDrawable에서 호출된 start() 메서드는 ActivityonCreate() 메서드 중에 호출할 수 없습니다. AnimationDrawable가 아직 창에 완전히 연결되지 않았기 때문입니다. 상호작용이 필요 없이 애니메이션을 즉시 재생하려면 ActivityonStart() 메서드에서 호출하면 됩니다. 이 메서드는 Android에서 화면에 보기를 표시할 때 호출됩니다.

XML 구문, 사용 가능한 태그 및 속성에 관한 자세한 내용은 애니메이션 리소스를 참고하세요.

AnimatedVectorDrawable 사용

벡터 드로어블은 픽셀화되거나 흐릿해지지 않고 확장 가능한 드로어블 유형입니다. AnimatedVectorDrawable 클래스 및 하위 호환성을 위한 AnimatedVectorDrawableCompat를 사용하면 벡터 드로어블을 회전하거나 경로 데이터를 변경하여 다른 이미지로 변형시키는 등 벡터 드로어블의 속성을 애니메이션 처리할 수 있습니다.

일반적으로 애니메이트된 벡터 드로어블은 다음 3개의 XML 파일에서 정의합니다.

  • res/drawable/<vector> 요소가 있는 벡터 드로어블
  • res/drawable/<animated-vector> 요소가 있는 애니메이션화된 벡터 드로어블
  • res/animator/<objectAnimator> 요소가 있는 하나 이상의 객체 애니메이터.

애니메이션 벡터 드로어블을 사용하면 <group><path> 요소의 속성에 애니메이션을 적용할 수 있습니다. <group> 요소는 경로 또는 하위 그룹의 집합을 정의하고 <path> 요소는 그릴 경로를 정의합니다.

애니메이션화할 벡터 드로어블을 정의할 때는 애니메이터 정의에서 참조할 수 있도록 android:name 속성을 사용하여 그룹 및 경로에 고유한 이름을 할당합니다. 예를 들면 다음과 같습니다.

res/drawable/vectordrawable.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

애니메이션화된 벡터 드로어블 정의는 벡터 드로어블에서 이름을 사용하여 그룹과 경로를 참조합니다.

res/drawable/animatorvectordrawable.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation" />
    <target
        android:name="v"
        android:animation="@animator/path_morph" />
</animated-vector>

애니메이션 정의는 ObjectAnimator 또는 AnimatorSet 객체를 나타냅니다. 이 예의 첫 번째 애니메이터는 타겟 그룹을 360도 회전합니다.

res/animator/rotation.xml

<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

이 예의 두 번째 애니메이터는 벡터 드로어블의 경로를 한 도형에서 다른 도형으로 모핑합니다. 경로는 모핑이 가능해야 합니다. 즉, 각 명령어에 대해 동일한 수의 명령어와 동일한 수의 매개변수가 있어야 합니다.

res/animator/path_morph.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>

결과 AnimatedVectorDrawable은 다음과 같습니다.

그림 2. AnimatedVectorDrawable.

애니메이션 벡터 드로어블(AVD) 미리보기

Android 스튜디오의 애니메이션 벡터 드로어블 도구를 사용하면 애니메이션 드로어블 리소스를 미리 볼 수 있습니다. 이 도구를 사용하면 Android 스튜디오에서 <animation-list>, <animated-vector>, <animated-selector> 리소스를 미리 보고 더 쉽게 맞춤 애니메이션을 미세 조정할 수 있습니다.

Android 스튜디오 내에서 사용자의 애니메이션 미리보기 및 재생
그림 3. Android 스튜디오의 Animated Vector Drawable 도구

자세한 내용은 AnimatedVectorDrawable의 API 참조를 확인하세요.