#894 - Basic port of InfoWindow

This commit is contained in:
Brad Leege
2015-08-28 20:12:33 -07:00
committed by Justin R. Miller
parent 7b93107869
commit 04f486cd7a
7 changed files with 332 additions and 15 deletions

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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()

View File

@@ -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>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
</resources>

View File

@@ -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>