Как обрабатывать событие onTouch для карты в Google Map API v2?

GoogleMap по умолчанию не предоставляет событие для начала перетаскивания карты и остановки перетаскивания. Я уже сообщал об этой проблеме.

Я хочу создать пользовательский handler, который будет использовать обычное событие onTouch и объединить его с setOnCameraChangeListener.

Однако мне не удалось найти способ доступа к событию onTouch объекта GoogleMap. Он не обеспечивает такой callback.

Интересно, как я могу обработать событие onTouch для карты в Google Map API v2?

Ответ 1

Ниже приведено возможное обходное решение для определения начальных и конечных событий перетаскивания:

Вы должны расширить SupportMapFragment или MapFragment. В onCreateView() вы должны обернуть свой MapView в настраиваемом FrameLayout (в примере ниже он представляет класс TouchableWrapper), в котором вы перехватываете события касания и узнаете, используется ли карта или нет. Если вы вызываете onCameraChange, просто проверьте, нажато ли отображение карты или нет (в примере ниже это переменная mMapIsTouched).

Пример кода:

ОБНОВЛЕНИЕ 1:

  • вернуть исходный созданный вид в getView()
  • используйте dispatchTouchEvent() вместо onInterceptTouchEvent()

Пользовательский FrameLayout:

private class TouchableWrapper extends FrameLayout {
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
        mMapIsTouched = true;
        break;

    case MotionEvent.ACTION_UP:
        mMapIsTouched = false;
        break;
        }

        return super.dispatchTouchEvent(ev);
    }
    }

В вашем настроенном MapFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);

    mTouchView = new TouchableWrapper(getActivity());
    mTouchView.addView(mOriginalContentView);

    return mTouchView;
}

@Override
public View getView() {
    return mOriginalContentView;
}

В вашем методе обратного вызова камеры:

private final OnCameraChangeListener mOnCameraChangeListener = new OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        if (!mMapIsTouched) {
            refreshClustering(false);
        }
    }
};

Ответ 2

Существует более простой способ сделать это, обработайте свои случаи на onCameraMoveStarted прослушивателе, подобном этому

Ниже фрагмента кода

@Override
public void onCameraMoveStarted(int reason) {
    if (reason == OnCameraMoveStartedListener.REASON_GESTURE) {
        Toast.makeText(this, "The user gestured on the map.",
                       Toast.LENGTH_SHORT).show();
    } else if (reason == OnCameraMoveStartedListener
                            .REASON_API_ANIMATION) {
        Toast.makeText(this, "The user tapped something on the map.",
                       Toast.LENGTH_SHORT).show();
    } else if (reason == OnCameraMoveStartedListener
                            .REASON_DEVELOPER_ANIMATION) {
        Toast.makeText(this, "The app moved the camera.",
                       Toast.LENGTH_SHORT).show();
    }
}