指定の位置に画像を配置 その2

Posted by muchag | Android |
初回投稿:2011-04-25 (月) 17:41:15 | 最終更新:2011-04-25 (月) 23:45:50

指定の位置に画像を配置
MapView の指定位置に画像を配置する手法を学習したが
別の手法も存在するようだ。

というのも、前の手法では、配置する画像が指定位置の右下に来ていたため
指定位置を中央とする手法を探していて発見した。

Android Developers:Google Map View Part 2: Adding Overlay Items

まず、ItemizedOverlay クラスを継承したサブクラスを作成する。

HelloItemizedOverlay.java
クラスファイルの作成

新しいクラスファイルを作成する際のダイアログで
① クラスファイル名(任意)入力
② スーパークラス入力
com.google.android.maps.ItemizedOverlay
③ 「スーパークラスからのコンストラクター」にチェック

 
とすると

  1. package com.example.sample;
  2.  
  3. import android.graphics.drawable.Drawable;
  4.  
  5. import com.google.android.maps.ItemizedOverlay;
  6. import com.google.android.maps.OverlayItem;
  7.  
  8. public class HelloItemizedOverlay extends ItemizedOverlay {
  9.  
  10.     public HelloItemizedOverlay(Drawable defaultMarker) {
  11.         super(defaultMarker);
  12.         // TODO 自動生成されたコンストラクター・スタブ
  13.     }
  14.  
  15.     @Override
  16.     protected OverlayItem createItem(int i) {
  17.         // TODO 自動生成されたメソッド・スタブ
  18.         return null;
  19.     }
  20.  
  21.     @Override
  22.     public int size() {
  23.         // TODO 自動生成されたメソッド・スタブ
  24.         return 0;
  25.     }
  26.  
  27. }

というクラスファイルが自動生成される。

自動生成の割には

ItemizedOverlay は raw 型です。総称型 ItemizedOverlay への参照は、パラメーター化する必要があります Java 問題

こんな警告が出てる。。。意味がわからない。。。後回し。。。
 

Overlay Item 格納コレクション

クラスのフィールドエリアに、Overlay Item を格納するための ArrayList コレクションを定義。

  1. private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();

 

Drawable 描画準備

Drawable リソースが描画されるために、メソッドを1つかます必要がある。

  1. public HelloItemizedOverlay(Drawable defaultMarker) {
  2.     super( boundCenterBottom(defaultMarker) );
  3.     populate(); // Android のバグ回避用
  4. }

これをかましていないと 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 を追加するためのメソッドを追加。

  1. public void addOverlay(OverlayItem overlay) {
  2.     mOverlays.add(overlay);
  3.     populate();
  4. }

 

createItem メソッドと size メソッドのオーバーライド

自動生成された createItem メソッドと size メソッドを以下のように変更。

  1. @Override
  2. protected OverlayItem createItem(int i) {
  3.     return mOverlays.get(i);
  4. }
  5.  
  6. @Override
  7. public int size() {
  8.     return mOverlays.size();
  9. }

 

タップイベントを拾うための準備

タップイベントを拾うために、コンストラクタに Context の参照を追加。

  1. private Context mContext;
  2.  
  3. public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
  4.     super( boundCenterBottom(defaultMarker) );
  5.     mContext = context;
  6.     populate(); // Android のバグ回避用
  7. }

 

タップイベント処理
  1. @Override
  2. protected boolean onTap(int index) {
  3.     OverlayItem item = mOverlays.get(index);
  4.     AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
  5.     dialog.setTitle(item.getTitle());
  6.     dialog.setMessage(item.getSnippet())
  7.     dialog.show();
  8.     return true;
  9. }

 

HelloGoogleMaps.java

ここで元になる MapActivity (ここでは、HelloGoogleMaps とする)クラスへ戻る。
 

アイコンの準備

MapView 上に Overlay Item として表示する画像を準備する。
上記 Android Developers サイトにロボットの画像があり、
「持ってなかったら、これを使っていいよ」と書いてある。

 
そして、「何なら自分のプロジェクトのリソースフォルダに D&D するといいよ」とも書いてある。
試しにやってみると、左のようなダイアログが出て、ちゃんと保存できた。
が、3jxz5leh.bmp というファイル名になった。
元々は androidmarker.png というファイル名。

ビットマップファイルに自動で変換してくれた、っていうことかしら。

 

onCreate メソッドに追加
  1. List<Overlay> mapOverlays = mapView.getOverlays();
  2. Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
  3. HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);

 

マーカー配置例

いよいよ具体的にマーカーを配置する手法。
onCreate メソッドに更に追加

  1. GeoPoint point = new GeoPoint(19240000,-99120000);
  2. OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");

マーカーを表示したい位置で GeoPoint インスタンスを生成し
それを、タイトルやメッセージと共に Overlay Item インスタンスへ渡す。
 
onCreate メソッドに更に追加

  1. itemizedoverlay.addOverlay(overlayitem);
  2. mapOverlays.add(itemizedoverlay);

最後に、今作った Overlay Item インスタンスを HelloItemizedOverlay インスタンスへ追加し
その HelloItemizedOverlay インスタンスを MapView の Overlay コレクションへ追加する。
 

完成例

 

HelloItemizedOverlay.java
  1. package com.example.sample;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. import android.app.AlertDialog;
  6. import android.content.Context;
  7. import android.graphics.drawable.Drawable;
  8.  
  9. import com.google.android.maps.ItemizedOverlay;
  10. import com.google.android.maps.OverlayItem;
  11.  
  12. public class HelloItemizedOverlay extends ItemizedOverlay {
  13.  
  14.     private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
  15.     private Context mContext;
  16.  
  17.     public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
  18.         super( boundCenterBottom(defaultMarker) );
  19.         mContext = context;
  20.         populate(); // Android のバグ回避用
  21.     }
  22.  
  23.     @Override
  24.     protected OverlayItem createItem(int i) {
  25.  
  26.         return mOverlays.get(i);
  27.     }
  28.  
  29.     @Override
  30.     public int size() {
  31.  
  32.         return mOverlays.size();
  33.     }
  34.  
  35.     public void addOverlay(OverlayItem overlay) {
  36.  
  37.         mOverlays.add(overlay);
  38.         populate();
  39.     }
  40.  
  41.     @Override
  42.     protected boolean onTap(int index) {
  43.  
  44.         OverlayItem item = mOverlays.get(index);
  45.         AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
  46.         dialog.setTitle(item.getTitle());
  47.         dialog.setMessage(item.getSnippet());
  48.         dialog.show();
  49.  
  50.         return true;
  51.     }
  52. }

 

HelloGoogleMaps.java
  1. package com.example.sample;
  2.  
  3. import java.util.List;
  4.  
  5. import android.graphics.drawable.Drawable;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.view.Window;
  9.  
  10. import com.google.android.maps.GeoPoint;
  11. import com.google.android.maps.MapActivity;
  12. import com.google.android.maps.MapView;
  13. import com.google.android.maps.Overlay;
  14. import com.google.android.maps.OverlayItem;
  15.  
  16. public class HospitalMap2 extends MapActivity {
  17.  
  18.     private MapView mapView; // MapView
  19.  
  20.     @Override
  21.     public void onCreate(Bundle savedInstanceState) {
  22.  
  23.         super.onCreate(savedInstanceState);
  24.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  25.  
  26.         // MapView のインスタンスを生成
  27.         mapView = new MapView(this, getResources().getString(R.string.map_key));
  28.         mapView.setEnabled(true);
  29.         mapView.setClickable(true);
  30.         mapView.setBuiltInZoomControls(true); // ズームボタンを有効
  31.         mapView.getController().setZoom(11); // ズーム度の初期値を設定
  32.         setContentView(mapView);
  33.  
  34.         List<Overlay> mapOverlays = mapView.getOverlays();
  35.         Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
  36.         HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
  37.  
  38.         GeoPoint point = new GeoPoint(19240000, -99120000);
  39.         OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
  40.  
  41.         itemizedoverlay.addOverlay(overlayitem);
  42.         mapOverlays.add(itemizedoverlay);
  43.     }
  44.  
  45.     @Override
  46.     protected boolean isRouteDisplayed() {
  47.         return false;
  48.     }
  49. }
Posted by muchag | Android |
初回投稿:2011-04-25 (月) 17:41:15 | 最終更新:2011-04-25 (月) 23:45:50

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment