5

Possible Duplicate:
Double Tap -> Zoom on Android MapView?

I have an Activity that extends MapActivity. I use Google Maps.
I need to zoom in by double clicking or double tapping.

Can someone help me with this?

I have already looked at the below, but they are not what I'm looking for.

Double Tap -> Zoom on Android MapView?

Fling gesture detection on grid layout

I realized that onTouchListener is being called only once, why is that so?

// set Gesture
detector = new GestureDetector(new GestureReactor());
mapView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("Inside onTouch");
        return detector.onTouchEvent(event);
    }
});

I have private class:

private class GestureReactor extends SimpleOnGestureListener {
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        System.out.println("inside onDouble");
        controller.zoomInFixing((int) e.getX(), (int) e.getY());
        return super.onDoubleTap(e);
    }
}

and

private GestureDetector detector;
Community
  • 1
  • 1
Varand Pezeshkian
  • 520
  • 2
  • 11
  • 22

6 Answers6

3

I had the same issue as bbodenmiller where everything worked fine until I had to cast to the newly made class. mapView = (MyMapView) findViewById(R.id.mapview); Would consistently throw an exception.

The solution is to change the XML layout where we are displaying the customized MapView. When you use a vanilla MapView your XML layout is something like this:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
    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="Hidden for obvious reasons"
/>

The problem lies in that "com.google.android.maps.MapView" defines the view as being specifically a MapView. You need to define it instead with your customized MapView. It ends up looking more like this.

<?xml version="1.0" encoding="utf-8"?>
<jocquej.PackageName.MyMapView
    ...
/>
Julian Jocque
  • 892
  • 10
  • 12
3

I've also been searching for an answer/example, but found nowhere working code.

Finally, here's the code that's working for me:

MyMapActivity.java

public class MyMapActivity extends MapActivity implements OnGestureListener,
OnDoubleTapListener{

private MapView mapView;

@Override
public void onCreate(Bundle savedInstanceState) {

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mapView = (MapView)findViewById(R.id.mapView);

}
@Override
public boolean onDoubleTap(MotionEvent e) {
     int x = (int)e.getX(), y = (int)e.getY();;  
     Projection p = mapView.getProjection();  
     mapView.getController().animateTo(p.fromPixels(x, y));
     mapView.getController().zoomIn();  
  return true; 
}
//Here will be some autogenerated methods too

OnDoubleTap.java

public class OnDoubleTap extends MapView {

  private long lastTouchTime = -1;

  public OnDoubleTap(Context context, AttributeSet attrs) {

    super(context, attrs);
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {

    if (ev.getAction() == MotionEvent.ACTION_DOWN) {

      long thisTime = System.currentTimeMillis();
      if (thisTime - lastTouchTime < 250) {

        // Double tap
        this.getController().zoomInFixing((int) ev.getX(), (int) ev.getY());
        lastTouchTime = -1;

      } else {

        // Too slow 
        lastTouchTime = thisTime;
      }
    }

    return super.onInterceptTouchEvent(ev);
  }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

        <azizbekyan.andranik.map.OnDoubleTap
            android:id="@+id/mapView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:enabled="true"
            android:clickable="true"
            android:apiKey="YOUR_API_KEY" />        
</LinearLayout>

Don't forget to replace here the android:apiKey value with your apiKey.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
3

Since you want a copy-paste answer, look here.

EDIT:

In my public class MainMap extends MapActivity I have a field called private MyMapView mv;

I then made a class which extends MapView like this: public class MyMapView extends MapView.

So you just make a new class which extends MapView, copy-paste the code you found in the link in there, and use your new class in your Activity which extends MapActivity.

iarwain01
  • 424
  • 3
  • 11
3

This solution is quite good http://nocivus.posterous.com/double-clicktap-detection-on-a

cesards
  • 15,882
  • 11
  • 70
  • 65
3

I love this solution of extending the MapView with a custom view and using that throughout your application. MapView has a function to intercept touch gestures which you can use to do some double click voodoo. If you have more than one map in your application, this is a great way to stay DRY.

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

import com.google.android.maps.MapView;

public class MyMapView extends MapView {
    private long lastTouchTime = -1;

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            long thisTime = System.currentTimeMillis();
            if (thisTime - lastTouchTime < ViewConfiguration.getDoubleTapTimeout()) {
                // Double tap
                this.getController().zoomInFixing((int) ev.getX(), (int) ev.getY());
                lastTouchTime = -1;
            } else {
                // Too slow :)
                lastTouchTime = thisTime;
            }
        }

        return super.onInterceptTouchEvent(ev);
    }
}

From this guy

bbodenmiller
  • 3,101
  • 5
  • 34
  • 50
gspatel
  • 1,128
  • 8
  • 12
0

I was unable to get http://nocivus.posterous.com/double-clicktap-detection-on-a to work as many others did as it would not allow me to cast mapView = (MyMapView) findViewById(R.id.mapview); that being said the best solution I got was based on the answer at Double Tap Zoom in GoogleMaps Activity:

myLocationOverlay = new MyLocationOverlay(this, mapView);

MyItemizedOverlay itemizedOverlay = new MyItemizedOverlay() {
    private long systemTime = System.currentTimeMillis();

    @Override
    public boolean onTouchEvent(MotionEvent event, MapView mapView) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if ((System.currentTimeMillis() - systemTime) < ViewConfiguration.getDoubleTapTimeout()) {
                mapController.zoomInFixing((int) event.getX(), (int) event.getY());
            }
            break;
        case MotionEvent.ACTION_UP:
            systemTime = System.currentTimeMillis();
            break;
        }

        return false;
    }
};
Community
  • 1
  • 1
bbodenmiller
  • 3,101
  • 5
  • 34
  • 50