#894 - Basic port of InfoWindow
This commit is contained in:
committed by
Justin R. Miller
parent
7b93107869
commit
04f486cd7a
@@ -2,7 +2,6 @@ package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import com.mapbox.mapboxgl.views.MapView;
|
||||
|
||||
|
||||
public abstract class Annotation {
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ public abstract class Annotation {
|
||||
* Internal C++ id is stored as unsigned int.
|
||||
*/
|
||||
protected long id = -1; // -1 unless added to a MapView
|
||||
private MapView mapView;
|
||||
protected MapView mapView;
|
||||
|
||||
float alpha = 1.0f;
|
||||
boolean visible = true;
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import com.mapbox.mapboxgl.geometry.LatLng;
|
||||
import com.mapbox.mapboxgl.views.MapView;
|
||||
|
||||
/**
|
||||
* A tooltip view
|
||||
*/
|
||||
public class InfoWindow {
|
||||
|
||||
private Marker boundMarker;
|
||||
private MapView mMapView;
|
||||
private boolean mIsVisible;
|
||||
protected View mView;
|
||||
|
||||
static int mTitleId = 0;
|
||||
static int mDescriptionId = 0;
|
||||
static int mSubDescriptionId = 0;
|
||||
static int mImageId = 0;
|
||||
|
||||
public InfoWindow(int layoutResId, MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mIsVisible = false;
|
||||
ViewGroup parent = (ViewGroup) mapView.getParent();
|
||||
Context context = mapView.getContext();
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mView = inflater.inflate(layoutResId, parent, false);
|
||||
|
||||
if (mTitleId == 0) {
|
||||
setResIds(mapView.getContext());
|
||||
}
|
||||
|
||||
// default behavior: close it when clicking on the tooltip:
|
||||
setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent e) {
|
||||
if (e.getAction() == MotionEvent.ACTION_UP) {
|
||||
close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public InfoWindow(View view, MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mIsVisible = false;
|
||||
ViewGroup parent = (ViewGroup) mapView.getParent();
|
||||
Context context = mapView.getContext();
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mView = view;
|
||||
|
||||
// default behavior: close it when clicking on the tooltip:
|
||||
setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent e) {
|
||||
if (e.getAction() == MotionEvent.ACTION_UP) {
|
||||
close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* open the window at the specified position.
|
||||
*
|
||||
* @param object the graphical object on which is hooked the view
|
||||
* @param position to place the window on the map
|
||||
* @param offsetX (&offsetY) the offset of the view to the position, in pixels.
|
||||
* This allows to offset the view from the object position.
|
||||
* @return this infowindow
|
||||
*/
|
||||
public InfoWindow open(Marker object, LatLng position, int offsetX, int offsetY) {
|
||||
onOpen(object);
|
||||
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
|
||||
MapView.LayoutParams.WRAP_CONTENT, Gravity.CENTER|Gravity.BOTTOM);
|
||||
close(); //if it was already opened
|
||||
mMapView.addView(mView, lp);
|
||||
mIsVisible = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this InfoWindow if it is visible, otherwise don't do anything.
|
||||
*
|
||||
* @return this info window
|
||||
*/
|
||||
public InfoWindow close() {
|
||||
if (mIsVisible) {
|
||||
mIsVisible = false;
|
||||
((ViewGroup) mView.getParent()).removeView(mView);
|
||||
// this.boundMarker.blur();
|
||||
setBoundMarker(null);
|
||||
onClose();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Android view. This allows to set its content.
|
||||
*
|
||||
* @return the Android view
|
||||
*/
|
||||
public View getView() {
|
||||
return mView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapView this InfoWindow is bound to
|
||||
*
|
||||
* @return the mapView
|
||||
*/
|
||||
public MapView getMapView() {
|
||||
return mMapView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the view that is displayed when the InfoWindow opens.
|
||||
* This retrieves data from overlayItem and shows it in the tooltip.
|
||||
*
|
||||
* @param overlayItem the tapped overlay item
|
||||
*/
|
||||
public void onOpen(Marker overlayItem) {
|
||||
String title = overlayItem.getTitle();
|
||||
((TextView) mView.findViewById(mTitleId /*R.id.title*/)).setText(title);
|
||||
String snippet = overlayItem.getSnippet();
|
||||
((TextView) mView.findViewById(mDescriptionId /*R.id.description*/)).setText(snippet);
|
||||
|
||||
/*
|
||||
//handle sub-description, hiding or showing the text view:
|
||||
TextView subDescText = (TextView) mView.findViewById(mSubDescriptionId);
|
||||
String subDesc = overlayItem.getSubDescription();
|
||||
if ("".equals(subDesc)) {
|
||||
subDescText.setVisibility(View.GONE);
|
||||
} else {
|
||||
subDescText.setText(subDesc);
|
||||
subDescText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
//by default, do nothing
|
||||
}
|
||||
|
||||
public InfoWindow setBoundMarker(Marker aBoundMarker) {
|
||||
this.boundMarker = aBoundMarker;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Marker getBoundMarker() {
|
||||
return boundMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a context, set the resource ids for the layout
|
||||
* of the InfoWindow.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private static void setResIds(Context context) {
|
||||
String packageName = context.getPackageName(); //get application package name
|
||||
mTitleId = context.getResources().getIdentifier("id/infowindow_title", null, packageName);
|
||||
mDescriptionId =
|
||||
context.getResources().getIdentifier("id/infowindow_description", null, packageName);
|
||||
mSubDescriptionId = context.getResources()
|
||||
.getIdentifier("id/infowindow_subdescription", null, packageName);
|
||||
mImageId = context.getResources().getIdentifier("id/infowindow_image", null, packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to override default touch events handling on InfoWindow (ie, close automatically)
|
||||
*
|
||||
* @param listener New View.OnTouchListener to use
|
||||
*/
|
||||
public void setOnTouchListener(View.OnTouchListener listener) {
|
||||
mView.setOnTouchListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class InfoWindowTipView extends View {
|
||||
|
||||
private Paint mPaint;
|
||||
private Path mPath;
|
||||
|
||||
public InfoWindowTipView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mPath = new Path();
|
||||
|
||||
this.mPaint = new Paint();
|
||||
this.mPaint.setColor(Color.WHITE);
|
||||
this.mPaint.setAntiAlias(true);
|
||||
this.mPaint.setStrokeWidth(0.0f);
|
||||
this.mPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int height = getMeasuredHeight();
|
||||
int width = getMeasuredWidth();
|
||||
|
||||
mPath.rewind();
|
||||
mPath.moveTo((width / 2) - height, 0);
|
||||
mPath.lineTo((width / 2) + height, 0);
|
||||
mPath.lineTo((width / 2), height);
|
||||
mPath.lineTo((width / 2) - height, 0);
|
||||
canvas.drawPath(mPath, this.mPaint);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.graphics.Point;
|
||||
import com.mapbox.mapboxgl.geometry.LatLng;
|
||||
|
||||
import com.mapbox.mapboxgl.views.R;
|
||||
|
||||
public class Marker extends Annotation {
|
||||
|
||||
@@ -16,10 +17,16 @@ public class Marker extends Annotation {
|
||||
String snippet;
|
||||
String sprite = "default_marker";
|
||||
String title;
|
||||
private InfoWindow infoWindow = null;
|
||||
|
||||
private boolean infoWindowShown = false;
|
||||
|
||||
public Marker() {}
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Marker() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* If two markers have the same LatLng, they are equal.
|
||||
@@ -41,6 +48,10 @@ public class Marker extends Annotation {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
public Point getAnchor() {
|
||||
return new Point((int)anchorU, (int)anchorV);
|
||||
}
|
||||
|
||||
public float getAnchorU() {
|
||||
return anchorU;
|
||||
}
|
||||
@@ -66,7 +77,7 @@ public class Marker extends Annotation {
|
||||
}
|
||||
|
||||
public void hideInfoWindow() {
|
||||
//TODO hideInfoWindow
|
||||
infoWindow.close();
|
||||
infoWindowShown = false;
|
||||
}
|
||||
|
||||
@@ -82,33 +93,33 @@ public class Marker extends Annotation {
|
||||
return infoWindowShown;
|
||||
}
|
||||
|
||||
void setAnchor(float u, float v) {
|
||||
public void setAnchor(float u, float v) {
|
||||
this.anchorU = u;
|
||||
this.anchorV = v;
|
||||
}
|
||||
|
||||
void setDraggable(boolean draggable) {
|
||||
public void setDraggable(boolean draggable) {
|
||||
this.draggable = draggable;
|
||||
}
|
||||
|
||||
void setFlat(boolean flat) {
|
||||
public void setFlat(boolean flat) {
|
||||
this.flat = flat;
|
||||
}
|
||||
|
||||
void setInfoWindowAnchor(float u, float v) {
|
||||
public void setInfoWindowAnchor(float u, float v) {
|
||||
infoWindowAnchorU = u;
|
||||
infoWindowAnchorV = v;
|
||||
}
|
||||
|
||||
void setPosition(LatLng latlng) {
|
||||
public void setPosition(LatLng latlng) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
void setRotation(float rotation) {
|
||||
public void setRotation(float rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
void setSnippet(String snippet) {
|
||||
public void setSnippet(String snippet) {
|
||||
this.snippet = snippet;
|
||||
}
|
||||
|
||||
@@ -120,18 +131,36 @@ public class Marker extends Annotation {
|
||||
*
|
||||
* @param sprite
|
||||
*/
|
||||
void setSprite(String sprite) {
|
||||
public void setSprite(String sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
void setTitle(String title) {
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
void showInfoWindow() {
|
||||
public void showInfoWindow() {
|
||||
|
||||
if (!isVisible() || mapView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (infoWindow == null) {
|
||||
infoWindow = new InfoWindow(R.layout.infowindow, mapView);
|
||||
}
|
||||
|
||||
infoWindow.open(this, getPosition(), (int)anchorU, (int)anchorV);
|
||||
infoWindow.setBoundMarker(this);
|
||||
infoWindowShown = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
super.setVisible(visible);
|
||||
if (!visible && infoWindowShown) {
|
||||
hideInfoWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Method in Google Maps Android API
|
||||
// public int hashCode()
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:background="@color/white"
|
||||
android:padding="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="18sp"
|
||||
android:maxEms="17"
|
||||
android:layout_gravity="left"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/infoWindowTitle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="14sp"
|
||||
android:maxEms="17"
|
||||
android:text="@string/infoWindowDescription"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_subdescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="12sp"
|
||||
android:maxEms="17"
|
||||
android:text="@string/infoWindowAddress"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<com.mapbox.mapboxgl.annotations.InfoWindowTipView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000000</color>
|
||||
</resources>
|
||||
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
|
||||
<string name="infoWindowTitle">Title</string>
|
||||
<string name="infoWindowDescription">Description</string>
|
||||
<string name="infoWindowAddress">Address</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user