
com.xtremelabs.robolectric.shadows.ShadowMapView Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robolectric Show documentation
Show all versions of robolectric Show documentation
An alternative Android testing framework.
The newest version!
package com.xtremelabs.robolectric.shadows;
import android.content.Context;
import android.graphics.Point;
import android.view.MotionEvent;
import android.widget.ZoomButtonsController;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.xtremelabs.robolectric.Robolectric;
import com.xtremelabs.robolectric.internal.Implementation;
import com.xtremelabs.robolectric.internal.Implements;
import java.util.ArrayList;
import java.util.List;
import static com.xtremelabs.robolectric.RobolectricForMaps.shadowOf;
/**
* Shadow of {@code MapView} that simulates the internal state of a {@code MapView}. Supports {@code Projection}s,
* {@code Overlay}s, and {@code TouchEvent}s
*/
@SuppressWarnings({"UnusedDeclaration"})
@Implements(MapView.class)
public class ShadowMapView extends ShadowViewGroup {
private boolean satelliteOn;
private MapController mapController;
private List overlays = new ArrayList();
GeoPoint mapCenter = new GeoPoint(10, 10);
int longitudeSpan = 20;
int latitudeSpan = 30;
int zoomLevel = 1;
private ShadowMapController shadowMapController;
private ZoomButtonsController zoomButtonsController;
private MapView realMapView;
private Projection projection;
private boolean useBuiltInZoomMapControls;
private boolean mouseDownOnMe = false;
private Point lastTouchEventPoint;
private GeoPoint mouseDownCenter;
private boolean preLoadWasCalled;
private boolean canCoverCenter = true;
public ShadowMapView(MapView mapView) {
realMapView = mapView;
zoomButtonsController = new ZoomButtonsController(mapView);
}
public void __constructor__(Context context, String title) {
super.__constructor__(context);
}
public static int toE6(double d) {
return (int) (d * 1e6);
}
public static double fromE6(int i) {
return i / 1e6;
}
@Implementation
public void setSatellite(boolean satelliteOn) {
this.satelliteOn = satelliteOn;
}
@Implementation
public boolean isSatellite() {
return satelliteOn;
}
@Implementation
public boolean canCoverCenter() {
return canCoverCenter;
}
@Implementation
public MapController getController() {
if (mapController == null) {
try {
mapController = Robolectric.newInstanceOf(MapController.class);
shadowMapController = shadowOf(mapController);
shadowMapController.setShadowMapView(this);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return mapController;
}
@Implementation
public ZoomButtonsController getZoomButtonsController() {
return zoomButtonsController;
}
@Implementation
public void setBuiltInZoomControls(boolean useBuiltInZoomMapControls) {
this.useBuiltInZoomMapControls = useBuiltInZoomMapControls;
}
@Implementation
public com.google.android.maps.Projection getProjection() {
if (projection == null) {
projection = new Projection() {
@Override public Point toPixels(GeoPoint geoPoint, Point point) {
if (point == null) {
point = new Point();
}
point.y = scaleDegree(geoPoint.getLatitudeE6(), bottom, top, mapCenter.getLatitudeE6(), latitudeSpan);
point.x = scaleDegree(geoPoint.getLongitudeE6(), left, right, mapCenter.getLongitudeE6(), longitudeSpan);
return point;
}
@Override public GeoPoint fromPixels(int x, int y) {
int lat = scalePixel(y, bottom, -realMapView.getHeight(), mapCenter.getLatitudeE6(), latitudeSpan);
int lng = scalePixel(x, left, realMapView.getWidth(), mapCenter.getLongitudeE6(), longitudeSpan);
return new GeoPoint(lat, lng);
}
@Override public float metersToEquatorPixels(float v) {
return 0;
}
};
}
return projection;
}
private int scalePixel(int pixel, int minPixel, int maxPixel, int centerDegree, int spanDegrees) {
int offsetPixels = pixel - minPixel;
double ratio = offsetPixels / ((double) maxPixel);
int minDegrees = centerDegree - spanDegrees / 2;
return (int) (minDegrees + spanDegrees * ratio);
}
private int scaleDegree(int degree, int minPixel, int maxPixel, int centerDegree, int spanDegrees) {
int minDegree = centerDegree - spanDegrees / 2;
int offsetDegrees = degree - minDegree;
double ratio = offsetDegrees / ((double) spanDegrees);
int spanPixels = maxPixel - minPixel;
return (int) (minPixel + spanPixels * ratio);
}
@Implementation
public List getOverlays() {
return overlays;
}
@Implementation
public GeoPoint getMapCenter() {
return mapCenter;
}
@Implementation
public int getLatitudeSpan() {
return latitudeSpan;
}
@Implementation
public int getLongitudeSpan() {
return longitudeSpan;
}
@Implementation
public int getZoomLevel() {
return zoomLevel;
}
@Implementation
@Override public boolean dispatchTouchEvent(MotionEvent event) {
for (Overlay overlay : overlays) {
if (overlay.onTouchEvent(event, realMapView)) {
return true;
}
}
GeoPoint mouseGeoPoint = getProjection().fromPixels((int) event.getX(), (int) event.getY());
int diffX = 0;
int diffY = 0;
if (mouseDownOnMe) {
diffX = (int) event.getX() - lastTouchEventPoint.x;
diffY = (int) event.getY() - lastTouchEventPoint.y;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mouseDownOnMe = true;
mouseDownCenter = getMapCenter();
break;
case MotionEvent.ACTION_MOVE:
if (mouseDownOnMe) {
moveByPixels(-diffX, -diffY);
}
break;
case MotionEvent.ACTION_UP:
if (mouseDownOnMe) {
moveByPixels(-diffX, -diffY);
mouseDownOnMe = false;
}
break;
case MotionEvent.ACTION_CANCEL:
getController().setCenter(mouseDownCenter);
mouseDownOnMe = false;
break;
}
lastTouchEventPoint = new Point((int) event.getX(), (int) event.getY());
return super.dispatchTouchEvent(event);
}
@Implementation
public void preLoad() {
preLoadWasCalled = true;
}
private void moveByPixels(int x, int y) {
Point center = getProjection().toPixels(mapCenter, null);
center.offset(x, y);
mapCenter = getProjection().fromPixels(center.x, center.y);
}
/**
* Non-Android accessor.
*
* @return whether to use built in zoom map controls
*/
public boolean getUseBuiltInZoomMapControls() {
return useBuiltInZoomMapControls;
}
/**
* Non-Android accessor.
*
* @return whether {@link #preLoad()} has been called on this {@code MapView}
*/
public boolean preLoadWasCalled() {
return preLoadWasCalled;
}
/**
* Non-Android accessor to set the latitude span (the absolute value of the difference between the Northernmost and
* Southernmost latitudes visible on the map) of this {@code MapView}
*
* @param latitudeSpan the new latitude span for this {@code MapView}
*/
public void setLatitudeSpan(int latitudeSpan) {
this.latitudeSpan = latitudeSpan;
}
/**
* Non-Android accessor to set the longitude span (the absolute value of the difference between the Easternmost and
* Westernmost longitude visible on the map) of this {@code MapView}
*
* @param longitudeSpan the new latitude span for this {@code MapView}
*/
public void setLongitudeSpan(int longitudeSpan) {
this.longitudeSpan = longitudeSpan;
}
/**
* Non-Android accessor that controls the value to be returned by {@link #canCoverCenter()}
*
* @param canCoverCenter the value to be returned by {@link #canCoverCenter()}
*/
public void setCanCoverCenter(boolean canCoverCenter) {
this.canCoverCenter = canCoverCenter;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy