画像をアニメーションさせるサンプル・プログラムの2つ目です。
2つ目は、日本Androidの会のメーリング・リストでやりとりされていた
以下のスレッドを参考にさせて頂きました。
参考サイト: OverlayにImageViewを表示する方法について
参考サイトでは、OverlayItem を使用しているのですが、
表示させたい画像(アニメーション)は1つしかないので、Overlay を使用するようにしました。
<設計方針>
Overlay を使います。
Overlay の draw() で画像を表示させるわけですが、画像を60枚用意しておき、
draw() が実行される都度、画像を切り替えるようにしておきます。
(最後の画像になったら、最初の画像に戻ります)
MapView に対して定期的に invalidate() を実行することで、Overlay の draw() が定期的に
実行されるようになり、パラパラ漫画(アニメーション)の完成です。
Overlay の draw() で画像を表示させるわけですが、画像を60枚用意しておき、
draw() が実行される都度、画像を切り替えるようにしておきます。
(最後の画像になったら、最初の画像に戻ります)
MapView に対して定期的に invalidate() を実行することで、Overlay の draw() が定期的に
実行されるようになり、パラパラ漫画(アニメーション)の完成です。
<問題点>
問題点でないですが、MapView に対して invalidate() を実行しているため、
複数の画像(静止画)があった場合、それらも再描画対象となるかなぁというのが気にかかります。
複数の画像(静止画)があった場合、それらも再描画対象となるかなぁというのが気にかかります。
以下にポイントとなるソースを貼り付けます。
まずはレイアウトです。
FrameLayout に対し、MapView のみを表示させています。
(子要素が MapView しかないので、FrameLayout である必要はないんですけど。)
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.google.android.maps.MapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
/>
</FrameLayout>次は Activity (MapActivity継承) クラスです。
onCreate() では、person_01.png ~ person_60.png の 60 枚の画像を読み込んでいます。
その後、アニメーションを行う Overlay を MapView に紐付けています。
MapTestActivity.java
package jp.kochi.test;
import java.util.ArrayList;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
public class MapTestActivity extends MapActivity {
ImageView mImageView;
AnimationOverlay mAnimOverlay;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v("MapTest", "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
ArrayList<Bitmap> list = new ArrayList<Bitmap>();
Resources r = getResources();
int id;
Bitmap bmp;
String str;
for (int i = 1; i <= 60; i++) {
str = "person_" + String.format("%1$02d", i);
id = r.getIdentifier(str, "drawable", getPackageName());
Log.v("MapTest", "str = " + str + ", id = " + id);
bmp = BitmapFactory.decodeResource(r, id);
list.add(bmp);
}
Log.v("MapTest", "list.size() = " + list.size());
// アニメーション表示
// お遍路さん2番札所
double latitude = 34.156028;
double longitude = 134.49025;
GeoPoint gpoint = new GeoPoint((int)(latitude * 1E6), (int)(longitude * 1E6));
List listOverlays = mapView.getOverlays();
mAnimOverlay = new AnimationOverlay(gpoint, list, mapView);
listOverlays.add(mAnimOverlay);
}
@Override
protected void onResume() {
Log.v("MapTest", "onResume()");
super.onResume();
mAnimOverlay.resume();
}
@Override
protected void onPause() {
Log.v("MapTest", "onPause()");
super.onPause();
mAnimOverlay.pause();
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}onResume()、onPause() では、Overlay のアニメーション (定期的に invalidate() 実行) を
再開/停止させる処理を追加しています。
最後は AnimationOverlay (Overlay継承) クラスです。
AnimationOverlay.java
package jp.kochi.test;
import java.util.ArrayList;
import java.util.List;
import android.R.bool;
import android.R.drawable;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
public class AnimationOverlay extends Overlay implements Runnable {
private Handler mHandler;
private ArrayList<Bitmap> mPngList;
private int current_frame;
private MapView mMapView;
private GeoPoint mGeoPoint;
final private int sInterval = 100;
private boolean mStop = false;
public AnimationOverlay(GeoPoint point, ArrayList<Bitmap> list,
MapView mview) {
Log.v("MapTest", "AnimationOverlay()");
mPngList = list;
mMapView = mview;
mGeoPoint = point;
current_frame = 0;
mHandler = new Handler();
mHandler.postDelayed(this, sInterval);
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
if (shadow == false) {
Log.v("MapTest", "draw() : shadow = false");
Point pxPoint = new Point();
Projection projection = mMapView.getProjection();
projection.toPixels(mGeoPoint, pxPoint);
canvas.drawBitmap(mPngList.get(current_frame), pxPoint.x,
pxPoint.y, null);
} else {
Log.v("MapTest", "draw() : shadow = true");
}
}
@Override
public void run() {
Log.v("MapTest", "run()");
if (current_frame == mPngList.size() - 1)
current_frame = 0;
else
current_frame++;
mMapView.invalidate();
if (mStop == false) mHandler.postDelayed(this, sInterval);
}
public void resume() {
mHandler.postDelayed(this, sInterval);
mStop = false;
}
public void pause() {
mStop = true;
}
}以下は実行画面です。
これもまた、分かりにくいですが、画面中央付近の画像が変化(アニメーション)しています。

