ドローアブル グラフィックをアニメーションにする

場合によっては、画像を画面上でアニメーション化する必要があります。複数の画像で構成されたカスタムの読み込みアニメーションを表示する場合や、ユーザーの操作後に別のアイコンに変化させる場合、この機能が役に立ちます。Android には、ドローアブルをアニメーション化するためのオプションがいくつか用意されています。

1 つめの方法は、Animation Drawable を使用することです。これにより、アニメーションを作成するために一度に 1 つずつ表示される複数の静的なドローアブル ファイルを指定できます。2 つめの方法は、Animated Vector Drawable を使用することです。これにより、ベクター型ドローアブルのプロパティをアニメーション化できます。

AnimationDrawable を使用する

Drawables をアニメーション化する方法の 1 つは、一連のドローアブル リソースを 1 つずつ読み込んでアニメーションを作成することです。一連の異なる画像で作成され、1 本のフィルムのように順番に再生されるという意味で、これは従来のアニメーションです。AnimationDrawable クラスがドローアブル アニメーションのベースになります。

AnimationDrawable クラス API を使用してコード内でアニメーションのフレームを定義することもできますが、1 つの XML ファイルで、アニメーションを構成するフレームをリストするほうが簡単です。この種のアニメーションの XML ファイルは、Android プロジェクトの res/drawable/ ディレクトリにあります。この場合、アニメーションの各フレームの順序と長さを指定します。

XML ファイルは、ルートノードとしての <animation-list> 要素と、それぞれがフレーム(フレームの描画可能リソースとフレームの長さ)を定義する一連の子 <item> ノードから構成されます。ドローアブル アニメーションの 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 に設定すると、1 回だけ通しで再生され、最後のフレームで停止したままになります。false に設定すると、アニメーションはループします。この XML ファイルを rocket_thrust.xml としてプロジェクトの res/drawable/ ディレクトリに保存すると、背景画像としてビューに追加され、再生のために呼び出されます。アニメーションが 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() })
    }
    

Java

    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() メソッドは、アクティビティの onCreate() メソッド中は、AnimationDrawable がまだウィンドウにアタッチされていないため呼び出せないことに注意が必要です。操作を必要とせずアニメーションをすぐに再生する場合は、Android が画面にビューを表示したときに呼び出されるアクティビティの onStart() メソッドから呼び出すことをおすすめします。

XML 構文、使用可能なタグと属性の詳細については、アニメーション リソースをご覧ください。

AnimatedVectorDrawable を使用する

ベクター型ドローアブルは、モザイク状にならずに、またはぼやけずに拡張可能なドローアブルの一種です。AnimatedVectorDrawable クラス(下位互換性には AnimatedVectorDrawableCompat)を使用すると、回転させたり、パスデータを変更して別の画像にしたりなど、ベクター型ドローアブルのプロパティをアニメーション化できます。

通常、アニメーション化ベクター型ドローアブルは、3 つの XML ファイルで定義します。

  • res/drawable/ の、<vector> 要素を持つベクター型ドローアブル
  • res/drawable/ の、<animated-vector> 要素を持つアニメーション化されたベクター型ドローアブル
  • res/animator/ の、<objectAnimator> 要素を持つ 1 つ以上のオブジェクト アニメーター

アニメーション化ベクター型ドローアブルでは、<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" />
    

この例の 2 つめのアニメーターは、ベクター型ドローアブルのパスを別の形状にモーフィングします。どちらのパスもモーフィングに対応している必要があります。つまり、各コマンドについて、同じ数のコマンドと同じ数のパラメータが必要です。

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 を次に示します。

詳細については、AnimatedVectorDrawable の API リファレンスをご覧ください。