OnTouchListener предотвращает перемещение карты

Я использую API карт Google, и у меня есть код, который пытается зафиксировать положение центра карты после того, как пользователь перетащил его.

MapView mv = ...;

mv.setOnTouchListener(new OnTouchListener() {

    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            GeoPoint pt = mv.getMapCenter();
            //do something with the point
            return A;
        }
        return B;
    }
});

Теперь моя проблема связана с возвращаемыми значениями:

  • если B ложно, карта перетаскивается, но я вижу только событие ACTION_DOWN, а ACTION_UP никогда не запускается, что я понимаю
  • если B истинно, я получаю событие ACTION_UP, но карта не перетаскивается
  • кажется, что истинно А или ложно, не имеет значения

Я хочу получить событие ACTION_UP И перетащить карту.

Что мне здесь не хватает?


person assylias    schedule 29.08.2012    source источник
comment
У меня была аналогичная проблема с обработкой прикосновений к маркерам просмотра карты, если onTouchEvent вернул true, карта никогда не сдвинется, когда я закодировал слушателя, чтобы он возвращал true ТОЛЬКО тогда, когда событие было поймано (чтобы сделать маркеры перетаскиваемыми), карта работала точно так, как предполагалось .   -  person Machinarius    schedule 30.08.2012
comment
@Drknezz при перетаскивании вы получаете одно событие ACTION_DOWN, затем несколько событий ACTION_MOVE и, наконец, событие ACTION_UP. Если я возвращаю true, карта не обновляется, если я возвращаю false, я вижу только ACTION_DOWN, но не следующие события...   -  person assylias    schedule 30.08.2012
comment
Может быть, вернуть вызов MapView.onTouchEvent(MotionEvent)? Таким образом, ваши вызовы не будут мешать поведению акций, и вы сможете поймать ACTION_UP для вычисления центра карты. Developers.google.com/maps/documentation/android/reference/com/   -  person Machinarius    schedule 30.08.2012


Ответы (2)


Вот одно из решений: вместо использования MapView по умолчанию используйте пользовательский MapView, который имеет GestureDetector, в основном это позволяет вам создать собственный прослушиватель событий для вашей карты, который поможет вам избежать проблем с перетаскиванием и т. д. и, кроме того, дает вам огромное количество вариантов взаимодействия по сравнению с MapView по умолчанию. Пару месяцев назад я столкнулся с похожей проблемой и решил реализовать только что упомянутое решение. Вот код для пользовательского MapView с именем TapControlledMapView, а код интерфейса для пользовательского прослушивателя приведен внизу: http://pastebin.com/kUrm9zFg.

Таким образом, для реализации слушателя все, что вам нужно сделать, это использовать следующий код в вашем классе активности карты (О, и в случае, если вы этого не знали, вы должны объявить следующее в своем XML-файле макета MapActivity, поскольку вы используете пользовательский Вид карты:

<?xml version="1.0" encoding="utf-8"?>
//The bottom line was the tricky business (You get ClassCastExceptions and whatnot)
<NAMEOFYOURPROJECT.TapControlledMapView (ex: com.android.googlemapsapp.TapControlledMapView)
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="API_KEY_HERE"
/>

и используйте следующий код в своем классе MapActivity.

mapView.setOnSingleTapListener(new OnSingleTapListener() {

@Override
 public boolean onSingleTap(MotionEvent arg1) {
 if(arg1.getAction() == MotionEvent.ACTION_UP)
 {
  GeoPoint pt = mv.getMapCenter();
  // do something with the point.
  return ***true***;
 }
return true;
});

Дайте мне знать, как это происходит.

person Vishwa Patel    schedule 30.08.2012
comment
Ура, не могли бы вы принять ответ, если он решил проблему? - person Vishwa Patel; 31.08.2012

Следуя идее @ViswaPatel, я создаю новый класс MapView, расширяющий MapView, который переопределяет метод onTouchEvent и управляет своими собственными слушателями:

public class CustomMapView extends MapView {

    private OnTouchListener lst;

    public CustomMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomMapView(Context context, String apiKey) {
        super(context, apiKey);
    }

    public void setOnActionUpListener(OnTouchListener lst) {
        this.lst = lst;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (lst != null && event.getAction() == MotionEvent.ACTION_UP) {
            lst.onTouch(this, event); // return value ignored
        }
        return true;
    }
}

Код вызова:

  mv.setOnActionUpListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            final GeoPoint pt = mv.getMapView().getMapCenter();
            //doing my stuff here
            return true; //ignored anyway
        }
    });
}
person assylias    schedule 30.08.2012