Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling touch events in SurfaceView over Maps API v2

I'm having issues in creating event handler that will be triggered while user moves the map around. There is a OnCameraChangeListener, but it is triggered after map moving stops.

I have created SurfaceView over Maps, and now I have no idea how to handle onScroll event from OnGestureListener.

Here is the sample code:

SurfaceView sv = new SView();
sv.setZOrderOnTop(true);
mapView.addView(sv);

...

public class SView extends SurfaceView implements Runnable, android.view.GestureDetector.OnGestureListener {
...
@Override
public boolean onTouchEvent(MotionEvent event) {
    //this worked in Overlay in Maps API v1
    if(gestureDetector.onTouchEvent(event)) {
        return true;
    }
    return false;
}
...

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    Log.i("test","onScroll");
    return false;
}

...
}

If I set return true in onTouchEvent, onScroll is called but than I can't move the Map (which is obvious, the event is consumed), and I don't know how to dispatch event down to Map object.

Anyone knows how to update SurfaceView while Map is moved?

like image 682
Miša Peić Avatar asked Jan 02 '13 12:01

Miša Peić


2 Answers

I have implemented some other solution to solve this problem. What I did - is I placed my GoogleMap inside custom RelativeLayout. After that onInterceptTouchEvent callback works like a charm and underlying map receives touch events as expected

here is my xml:

<com.my.package.name.map.MapRelativeLayout
    android:id="@+id/map_root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

     <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>

</com.my.package.name.map.MapRelativeLayout>

And custom relative layout:

package com.my.package.name.map;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

public class MapRelativeLayout extends RelativeLayout
{
    private GestureDetector gestureDetector;

    public MapRelativeLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        gestureDetector.onTouchEvent(ev);
        return false;
    }

    private class GestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY)
        {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY)
        {
            //do whatever you want here
            return false;
        }
    }
}
like image 153
Pavel Dudka Avatar answered Nov 19 '22 18:11

Pavel Dudka


From: Android ListView: overriding causes scrolling do not executed

Have you tried calling super.onTouchEvent(event) in your onTouchEvent method?

Edit - I think you want to return false as well in your onScroll method.

Then your onTouchEvent method should be:

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (gestureDetector.onTouchEvent(event)) {
        return true;
    }
    return super.onTouchEvent(event);
}

Other possible helpful links:

  • Android: how to tell if a view is scrolling
  • Adding GestureOverlayView to my SurfaceView class, how to add to view hierarchy?
  • Android onFling not responding
  • OnGestureListener onDown method never gets called
  • Overriding onTouchEvent competing with ScrollView
like image 31
JSuar Avatar answered Nov 19 '22 19:11

JSuar