指定の位置に画像を配置 で
MapView の指定位置に画像を配置する手法を学習したが
別の手法も存在するようだ。
というのも、前の手法では、配置する画像が指定位置の右下に来ていたため
指定位置を中央とする手法を探していて発見した。
Android Developers:Google Map View Part 2: Adding Overlay Items
まず、ItemizedOverlay クラスを継承したサブクラスを作成する。
HelloItemizedOverlay.java
クラスファイルの作成
新しいクラスファイルを作成する際のダイアログで
① クラスファイル名(任意)入力
② スーパークラス入力
com.google.android.maps.ItemizedOverlay
③ 「スーパークラスからのコンストラクター」にチェック
とすると
[android]package com.example.sample;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class HelloItemizedOverlay extends ItemizedOverlay {
public HelloItemizedOverlay(Drawable defaultMarker) {
super(defaultMarker);
// TODO 自動生成されたコンストラクター・スタブ
}
@Override
protected OverlayItem createItem(int i) {
// TODO 自動生成されたメソッド・スタブ
return null;
}
@Override
public int size() {
// TODO 自動生成されたメソッド・スタブ
return 0;
}
}[/android]
というクラスファイルが自動生成される。
自動生成の割には
ItemizedOverlay は raw 型です。総称型 ItemizedOverlay- への参照は、パラメーター化する必要があります Java 問題
こんな警告が出てる。。。意味がわからない。。。後回し。。。
Overlay Item 格納コレクション
クラスのフィールドエリアに、Overlay Item を格納するための ArrayList コレクションを定義。
[android]private ArrayList mOverlays = new ArrayList();[/android]
Drawable 描画準備
Drawable リソースが描画されるために、メソッドを1つかます必要がある。
[android]public HelloItemizedOverlay(Drawable defaultMarker) {
super( boundCenterBottom(defaultMarker) );
populate(); // Android のバグ回避用
}[/android]
これをかましていないと LogCat に以下のようなエラーが出て、マーカーが表示されない。
ERROR/MapActivity(226): Couldn’t get connection factory client
(かまさない時だけこのエラーが出るので、そうだと思う)
boundCenter
指定 GeoPoint が Drawable の中心にくるように指定。
boundCenterBottom
指定 GeoPoint が Drawable の下辺中央にくるように指定。
Android のバグ
また、Android にバグがあるため、バグ回避用に populate メソッドも追加。
参考元サイト:とあるSEのリマインダー
MapViewでItemizedOverlayでアイテムが設定されていないとNullpointer Exceptionが発生
Overlay Item 追加メソッド
Overlay Item を追加するためのメソッドを追加。
[android]public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}[/android]
createItem メソッドと size メソッドのオーバーライド
自動生成された createItem メソッドと size メソッドを以下のように変更。
[android]@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}[/android]
タップイベントを拾うための準備
タップイベントを拾うために、コンストラクタに Context の参照を追加。
[android]private Context mContext;
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super( boundCenterBottom(defaultMarker) );
mContext = context;
populate(); // Android のバグ回避用
}[/android]
タップイベント処理
[android]@Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet())
dialog.show();
return true;
}[/android]
HelloGoogleMaps.java
ここで元になる MapActivity (ここでは、HelloGoogleMaps とする)クラスへ戻る。
アイコンの準備
MapView 上に Overlay Item として表示する画像を準備する。
上記 Android Developers サイトにロボットの画像があり、
「持ってなかったら、これを使っていいよ」と書いてある。
そして、「何なら自分のプロジェクトのリソースフォルダに D&D するといいよ」とも書いてある。
試しにやってみると、左のようなダイアログが出て、ちゃんと保存できた。
が、3jxz5leh.bmp というファイル名になった。
元々は androidmarker.png というファイル名。
ビットマップファイルに自動で変換してくれた、っていうことかしら。
onCreate メソッドに追加
[android]List
mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);[/android]
マーカー配置例
いよいよ具体的にマーカーを配置する手法。
onCreate メソッドに更に追加
[android]GeoPoint point = new GeoPoint(19240000,-99120000);
OverlayItem overlayitem = new OverlayItem(point, “Hola, Mundo!”, “I’m in Mexico City!”);[/android]
マーカーを表示したい位置で GeoPoint インスタンスを生成し
それを、タイトルやメッセージと共に Overlay Item インスタンスへ渡す。
onCreate メソッドに更に追加
[android]itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);[/android]
最後に、今作った Overlay Item インスタンスを HelloItemizedOverlay インスタンスへ追加し
その HelloItemizedOverlay インスタンスを MapView の Overlay コレクションへ追加する。
完成例
HelloItemizedOverlay.java
[android]package com.example.sample;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class HelloItemizedOverlay extends ItemizedOverlay {
private ArrayList mOverlays = new ArrayList();
private Context mContext;
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super( boundCenterBottom(defaultMarker) );
mContext = context;
populate(); // Android のバグ回避用
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}[/android]
HelloGoogleMaps.java
[android]package com.example.sample;
import java.util.List;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class HospitalMap2 extends MapActivity {
private MapView mapView; // MapView
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// MapView のインスタンスを生成
mapView = new MapView(this, getResources().getString(R.string.map_key));
mapView.setEnabled(true);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true); // ズームボタンを有効
mapView.getController().setZoom(11); // ズーム度の初期値を設定
setContentView(mapView);
List mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
GeoPoint point = new GeoPoint(19240000, -99120000);
OverlayItem overlayitem = new OverlayItem(point, “Hola, Mundo!”, “I’m in Mexico City!”);
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
}[/android]