GoogleMapのアイコンタップ
- Android
-
2011-12-21 - 更新:2011-12-22
この記事は最終更新日から1年以上経過しています。
GoogleMapにアイコンを表示し、タップすると何らかの処理をしたいとき、通常のonTapメソッドで処理を実行しようとすると、地図の拡大縮小時、アイコンに指が触れているとタップされたことになってしまいます。
これを回避するために、ジェスチャーリスナーを実装し、シングルタップアップにて処理をするようにします。
android.view.GestureDetector.OnGestureListener
public class PinItemizedOverlay extends ItemizedOverlay<OverlayItem> implements OnGestureListener {
private List<GeoPoint> points = new ArrayList<GeoPoint>();
private Context context;
private GestureDetector gestureDetector = null;
private MapView mMapView;
private Drawable defaultMarker;
public PinItemizedOverlay(Drawable defaultMarker, Context context) {
super( boundCenterBottom(defaultMarker) );
setLastFocusedIndex(-1);
populate();
this.context = context;
this.defaultMarker = defaultMarker;
gestureDetector = new GestureDetector(this);
}
@Override
protected OverlayItem createItem(int i) {
GeoPoint point = points.get(i);
OverlayItem overlayItem = new OverlayItem(point, null, null);
overlayItem.setMarker(boundCenterBottom(defaultMarker)); //これをしないとhitTestでNullPointerExceptionが発生します。
return overlayItem;
}
@Override
public int size() {
return points.size();
}
public void addPin(GeoPoint point, String title, String snippet, int icontype) {
if (getIndexGeoPoint(point) == -1) {
this.points.add(point);
this.icontype.add(icontype);
}
setLastFocusedIndex(-1);
populate();
}
// 位置が一致するか(一致しない場合は -1を返す)
private int getIndexGeoPoint(GeoPoint newPoint) {
int result = -1;
int size = this.points.size();
for (int i = 0; i < size; i++) {
GeoPoint point = this.points.get(i);
if (point.equals(newPoint)) {
result = i;
break;
}
}
return result;
}
private int hitTest(Projection pj, int x, int y){
int hitIndex = -1;
String TAG = "hitTest";
Point hitPoint = new Point(x, y);
for(int i = 0; i < this.points.size(); i++){
OverlayItem item = getItem(i);
Point point = new Point();
pj.toPixels(item.getPoint(), point);
int halfWidth = item.getMarker(0).getIntrinsicWidth() / 2;
int left = point.x - halfWidth;
int right = point.x + halfWidth;
int top = point.y - item.getMarker(0).getIntrinsicHeight();
int bottom = point.y;
//Log.d(TAG, "left: " + left);
//Log.d(TAG, "rihgt: " + right);
//Log.d(TAG, "top: " + top);
//Log.d(TAG, "bottom: " + bottom);
//Log.d(TAG, "hitX: " + hitPoint.x);
//Log.d(TAG, "hitY: " + hitPoint.y);
if(left <= hitPoint.x && hitPoint.x <= right){
if(top <= hitPoint.y && hitPoint.y <= bottom){
Log.d(TAG, "left: " + left);
Log.d(TAG, "rihgt: " + right);
Log.d(TAG, "top: " + top);
Log.d(TAG, "bottom: " + bottom);
Log.d(TAG, "hitX: " + hitPoint.x);
Log.d(TAG, "hitY: " + hitPoint.y);
hitIndex = i;
return i;
}
}
}
return hitIndex;
}
private void onMyTap(int index) {
if (points.size() < index) {
return;
}
// ここにタップ時の処理を記述
}
public void clearPoint() {
this.points.clear();
setLastFocusedIndex(-1);
populate();
}
@Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
// GestureDetector にタッチイベントを詳細化してもらう
gestureDetector.onTouchEvent(e);
mMapView = mapView;
return super.onTouchEvent(e, mapView);
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
int hitIndex = hitTest(this.mMapView.getProjection(), (int)e.getX(), (int)e.getY());
Log.v("onSingleTapUp", String.valueOf(hitIndex));
if (hitIndex != -1) {
onMyTap(hitIndex);
}
return false;
}
}
参考にさせていただいたURL
http://d.hatena.ne.jp/sei10sa10/20110802/1312288744
この記事がお役に立ちましたらシェアお願いします
3,008 views




