なか日記

一度きりの人生、楽しく生きよう。

SDカード内の画像をアニメーションさせる

SDカード内の画像をアニメーションさせる方法に関するサンプルです。
変なこと書いてたら遠慮なくツッコミお願いします。

事前に画像を特定出来る(アプリに組み込める)場合は、画像を予めdrawableに配置した上でXMLで指定するのが手っ取り早くてオススメです。
詳細はテックファームさんが紹介されている「XMLでのアニメーション|AnimationDrawable | Android Techfirm Lab」をご覧下さい。

サンプルソース

動けばいいやって感じなので、かなり適当。
EclipseAndroidプロジェクトを新規作成し、Activityを継承したクラスを書き換えています。他のXMLファイル等に修正はしてません。

package com.nakaji.android.animationsample;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;

public class AnimationSampleActivity extends Activity {

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		BitmapDrawable bmp1 = new BitmapDrawable("/sdcard/WS000004.JPG");
		BitmapDrawable bmp2 = new BitmapDrawable("/sdcard/WS000015.JPG");

		AnimationDrawable drawable = new AnimationDrawable();
		drawable.addFrame(bmp1, 1000);
		drawable.addFrame(bmp2, 2000);
		drawable.setOneShot(false);

		ImageView iv = new ImageView(this);
		iv.setBackgroundDrawable(drawable);

		iv.post(new Starter(drawable));
		setContentView(iv);
	}

	class Starter implements Runnable {
		AnimationDrawable _drawable;

		private Starter() {
		}

		public Starter(AnimationDrawable drawable) {
			_drawable = drawable;
		}

		@Override
		public void run() {
			_drawable.start();
		}
	}
}

ざっと以下の様な流れです。

  1. 画像ファイルのパスを指定して、BitmapDrawableオブジェクトを作成
  2. AnimationDrawableオブジェクトのフレームにBitmapDrawableオブジェクトを追加
  3. ImageViewオブジェクトにAnimationDrawableオブジェクトをセット
  4. AnimationDrawableオブジェクトのstartメソッドを呼び出して、アニメーションを開始する

ポイント

SDカード内の画像をアニメーションさせるのとは関係ありませんが、Activityが起動した時からアニメーションが開始するよう、一連の処理をonCreateメソッド内で行っています。
ここではまったのですが、onCreate はUIスレッドで動いてる訳じゃないので、この中でAnimationDrawableのstartメソッドを実行してもうまくいきません。
UIスレッドで処理が実行されるようにするためには、Runnableインターフェースを実装したクラスのインスタンスをImageViewのpostメソッド*1に渡してやる必要があります。

2010/06/21追記

AnimationDrawableの変数をfinal宣言しないといけませんが、以下の様な書き方も出来ますね。と。

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		BitmapDrawable bmp1 = new BitmapDrawable("/sdcard/WS000004.JPG");
		BitmapDrawable bmp2 = new BitmapDrawable("/sdcard/WS000015.JPG");

		final AnimationDrawable drawable = new AnimationDrawable();
		drawable.addFrame(bmp1, 1000);
		drawable.addFrame(bmp2, 2000);
		drawable.setOneShot(false);

		ImageView iv = new ImageView(this);
		iv.setBackgroundDrawable(drawable);

		iv.post(new Runnable() {
			@Override
			public void run() {
				drawable.start();
			}
		});
		setContentView(iv);
	}

*1:http://developer.android.com/intl/ja/reference/android/view/View.html#post%28java.lang.Runnable%29