私はこれについて何日も頭を悩ませており、Googleで検索してSOを検索しましたが、そのような問題を報告している他の人を見つけることができないようです(見逃した可能性があります)。
とりわけロングプレスをリッスンするカスタマイズされたMapviewクラスがあり、それを使用してマップにマーカーをプロットしています。API-8で問題なくプロットされます。しかし、API-15 では、ユーザーの指が長押しを行っている場所の下にマーカーが約 2cm ずれています。これは、実際のデバイス (samsung s2) と Eclipse エミュレーターの両方で観察されます。また、長押しされた指の領域とプロットされたマーカーの領域 (約 2 cm のオフセット) は、すべてのズーム レベルで観察されます。
これが私のカスタマイズされたMapviewクラスです(どこかからヤンクしました):
public class MyCustomMapView extends MapView {
public interface OnLongpressListener {
public void onLongpress(MapView view, GeoPoint longpressLocation);
}
static final int LONGPRESS_THRESHOLD = 500;
private GeoPoint lastMapCenter;
private Timer longpressTimer = new Timer();
private MyCustomMapView.OnLongpressListener longpressListener;
public MyCustomMapView(Context context, String apiKey) {
super(context, apiKey);
}
public MyCustomMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyCustomMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setOnLongpressListener(MyCustomMapView.OnLongpressListener listener) {
longpressListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
handleLongpress(event);
return super.onTouchEvent(event);
}
private void handleLongpress(final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Finger has touched screen.
longpressTimer = new Timer();
longpressTimer.schedule(new TimerTask() {
@Override
public void run() {
GeoPoint longpressLocation = getProjection().fromPixels((int)event.getX(), (int)event.getY());
/*
* Fire the listener. We pass the map location
* of the longpress as well, in case it is needed
* by the caller.
*/
longpressListener.onLongpress(MyCustomMapView.this, longpressLocation);
}
}, LONGPRESS_THRESHOLD);
lastMapCenter = getMapCenter();
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!getMapCenter().equals(lastMapCenter)) {
// User is panning the map, this is no longpress
longpressTimer.cancel();
}
lastMapCenter = getMapCenter();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
// User has removed finger from map.
longpressTimer.cancel();
}
if (event.getPointerCount() > 1) {
// This is a multitouch event, probably zooming.
longpressTimer.cancel();
}
}
そして、これは私が上記のクラスを呼び出す方法です:
custom_marker = getResources().getDrawable(R.drawable.marker3);
custom_marker.setBounds(-custom_marker.getIntrinsicWidth(), -custom_marker.getIntrinsicHeight(), 0, 0);
customSitesOverlay = new CustomSitesOverlay(custom_marker);
mapView.getOverlays().add(customSitesOverlay);
customSitesOverlay.addOverlay(new OverlayItem(longpressLocation, "User Marker", id));