[WIP] InfoWindow refactor (#8080)

* [android] remove unnecessary info window class and add bubble layout

* fix some PR comments (remove hungarian notation, make bubble popup helper package protected and fix some code style issues)

* refactor replace enum in favor of intdef

* make bubble layout package protected and remove useless info window tip view class
This commit is contained in:
Pablo Guardiola
2017-02-28 11:48:40 -05:00
committed by GitHub
parent 8e9d6a5b2c
commit 283aee0754
13 changed files with 773 additions and 245 deletions

View File

@@ -0,0 +1,30 @@
package com.mapbox.mapboxsdk.annotations;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
class ArrowDirection {
@IntDef( {LEFT, RIGHT, TOP, BOTTOM})
@Retention(RetentionPolicy.SOURCE)
@interface Value {
}
static final int LEFT = 0;
static final int RIGHT = 1;
static final int TOP = 2;
static final int BOTTOM = 3;
@Value
private final int value;
ArrowDirection(@Value int value) {
this.value = value;
}
@Value
public int getValue() {
return value;
}
}

View File

@@ -0,0 +1,311 @@
package com.mapbox.mapboxsdk.annotations;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
class Bubble extends Drawable {
private RectF rect;
private float arrowWidth;
private float arrowHeight;
private float arrowPosition;
private float cornersRadius;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float strokeWidth;
private Paint strokePaint;
private Path strokePath;
private Path path = new Path();
Bubble(RectF rect, ArrowDirection arrowDirection, float arrowWidth, float arrowHeight, float arrowPosition,
float cornersRadius, int bubbleColor, float strokeWidth, int strokeColor) {
this.rect = rect;
this.arrowWidth = arrowWidth;
this.arrowHeight = arrowHeight;
this.arrowPosition = arrowPosition;
this.cornersRadius = cornersRadius;
paint.setColor(bubbleColor);
this.strokeWidth = strokeWidth;
if (strokeWidth > 0) {
strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
strokePaint.setColor(strokeColor);
strokePath = new Path();
initPath(arrowDirection, path, strokeWidth);
initPath(arrowDirection, strokePath, 0);
} else {
initPath(arrowDirection, path, 0);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
}
@Override
public void draw(Canvas canvas) {
if (strokeWidth > 0) {
canvas.drawPath(strokePath, strokePaint);
}
canvas.drawPath(path, paint);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
@Override
public int getIntrinsicWidth() {
return (int) rect.width();
}
@Override
public int getIntrinsicHeight() {
return (int) rect.height();
}
private void initPath(ArrowDirection arrowDirection, Path path, float strokeWidth) {
switch (arrowDirection.getValue()) {
case ArrowDirection.LEFT:
if (cornersRadius <= 0) {
initLeftSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initLeftSquarePath(rect, path, strokeWidth);
break;
}
initLeftRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.TOP:
if (cornersRadius <= 0) {
initTopSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initTopSquarePath(rect, path, strokeWidth);
break;
}
initTopRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.RIGHT:
if (cornersRadius <= 0) {
initRightSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initRightSquarePath(rect, path, strokeWidth);
break;
}
initRightRoundedPath(rect, path, strokeWidth);
break;
case ArrowDirection.BOTTOM:
if (cornersRadius <= 0) {
initBottomSquarePath(rect, path, strokeWidth);
break;
}
if (strokeWidth > 0 && strokeWidth > cornersRadius) {
initBottomSquarePath(rect, path, strokeWidth);
break;
}
initBottomRoundedPath(rect, path, strokeWidth);
break;
}
}
private void initLeftSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(arrowWidth + rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2));
path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initLeftRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(arrowWidth + rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.top + strokeWidth, rect.right - strokeWidth,
cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius,
rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + cornersRadius + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left + arrowWidth, rect.bottom - strokeWidth), 90, 90);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2));
path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left + arrowWidth, cornersRadius + rect.top), 180, 90);
path.close();
}
private void initTopSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth);
path.close();
}
private void initTopRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + Math.min(arrowPosition, cornersRadius) + strokeWidth, rect.top + arrowHeight
+ strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth);
path.lineTo(rect.right - cornersRadius - strokeWidth, rect.top + arrowHeight + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius,
rect.top + arrowHeight + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top + arrowHeight),
270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius,
rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + cornersRadius + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90);
path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top + arrowHeight), 180, 90);
path.close();
}
private void initRightSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - arrowWidth - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2));
path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initRightRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - arrowWidth - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth,
rect.top + strokeWidth, rect.right - arrowWidth - strokeWidth, cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2));
path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2);
path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2));
path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth, rect.bottom - cornersRadius,
rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius,
cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top), 180, 90);
path.close();
}
private void initBottomSquarePath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth);
path.close();
}
private void initBottomRoundedPath(RectF rect, Path path, float strokeWidth) {
path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth);
path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius,
rect.top + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top), 270, 90);
path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - cornersRadius - strokeWidth);
path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius - arrowHeight,
rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth), 0, 90);
path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth);
path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth);
path.lineTo(rect.left + Math.min(cornersRadius, arrowPosition) + strokeWidth, rect.bottom - arrowHeight
- strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius - arrowHeight,
cornersRadius + rect.left, rect.bottom - arrowHeight - strokeWidth), 90, 90);
path.lineTo(rect.left + strokeWidth, rect.top + cornersRadius + strokeWidth);
path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius
+ rect.left, cornersRadius + rect.top), 180, 90);
path.close();
}
}

View File

@@ -0,0 +1,231 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;
import com.mapbox.mapboxsdk.R;
/**
* Bubble View for Android with custom stroke width and color, arrow size, position and direction.
*/
class BubbleLayout extends LinearLayout {
public static final float DEFAULT_STROKE_WIDTH = -1;
private ArrowDirection arrowDirection;
private float arrowWidth;
private float arrowHeight;
private float arrowPosition;
private float cornersRadius;
private Bubble bubble;
private int bubbleColor;
private float strokeWidth;
private int strokeColor;
public BubbleLayout(Context context) {
this(context, null, 0);
}
public BubbleLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BubbleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.mapbox_BubbleLayout);
@ArrowDirection.Value
int location = a.getInt(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowDirection,
ArrowDirection.LEFT);
arrowDirection = new ArrowDirection(location);
arrowWidth = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowWidth,
convertDpToPixel(8, context));
arrowHeight = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowHeight,
convertDpToPixel(8, context));
arrowPosition = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowPosition,
convertDpToPixel(12, context));
cornersRadius = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_cornersRadius, 0);
bubbleColor = a.getColor(R.styleable.mapbox_BubbleLayout_mapbox_bl_bubbleColor, Color.WHITE);
strokeWidth =
a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_strokeWidth, DEFAULT_STROKE_WIDTH);
strokeColor = a.getColor(R.styleable.mapbox_BubbleLayout_mapbox_bl_strokeColor, Color.GRAY);
a.recycle();
initPadding();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
initDrawable(0, getWidth(), 0, getHeight());
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (bubble != null) {
bubble.draw(canvas);
}
super.dispatchDraw(canvas);
}
static float convertDpToPixel(float dp, Context context) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
public ArrowDirection getArrowDirection() {
return arrowDirection;
}
public BubbleLayout setArrowDirection(ArrowDirection arrowDirection) {
resetPadding();
this.arrowDirection = arrowDirection;
initPadding();
return this;
}
public float getArrowWidth() {
return arrowWidth;
}
public BubbleLayout setArrowWidth(float arrowWidth) {
resetPadding();
this.arrowWidth = arrowWidth;
initPadding();
return this;
}
public float getArrowHeight() {
return arrowHeight;
}
public BubbleLayout setArrowHeight(float arrowHeight) {
resetPadding();
this.arrowHeight = arrowHeight;
initPadding();
return this;
}
public float getArrowPosition() {
return arrowPosition;
}
public BubbleLayout setArrowPosition(float arrowPosition) {
resetPadding();
this.arrowPosition = arrowPosition;
initPadding();
return this;
}
public float getCornersRadius() {
return cornersRadius;
}
public BubbleLayout setCornersRadius(float cornersRadius) {
this.cornersRadius = cornersRadius;
requestLayout();
return this;
}
public int getBubbleColor() {
return bubbleColor;
}
public BubbleLayout setBubbleColor(int bubbleColor) {
this.bubbleColor = bubbleColor;
requestLayout();
return this;
}
public float getStrokeWidth() {
return strokeWidth;
}
public BubbleLayout setStrokeWidth(float strokeWidth) {
resetPadding();
this.strokeWidth = strokeWidth;
initPadding();
return this;
}
public int getStrokeColor() {
return strokeColor;
}
public BubbleLayout setStrokeColor(int strokeColor) {
this.strokeColor = strokeColor;
requestLayout();
return this;
}
private void initPadding() {
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
switch (arrowDirection.getValue()) {
case ArrowDirection.LEFT:
paddingLeft += arrowWidth;
break;
case ArrowDirection.RIGHT:
paddingRight += arrowWidth;
break;
case ArrowDirection.TOP:
paddingTop += arrowHeight;
break;
case ArrowDirection.BOTTOM:
paddingBottom += arrowHeight;
break;
}
if (strokeWidth > 0) {
paddingLeft += strokeWidth;
paddingRight += strokeWidth;
paddingTop += strokeWidth;
paddingBottom += strokeWidth;
}
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
private void initDrawable(int left, int right, int top, int bottom) {
if (right < left || bottom < top) {
return;
}
RectF rectF = new RectF(left, top, right, bottom);
bubble = new Bubble(rectF, arrowDirection, arrowWidth, arrowHeight, arrowPosition, cornersRadius,
bubbleColor, strokeWidth, strokeColor);
}
private void resetPadding() {
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
switch (arrowDirection.getValue()) {
case ArrowDirection.LEFT:
paddingLeft -= arrowWidth;
break;
case ArrowDirection.RIGHT:
paddingRight -= arrowWidth;
break;
case ArrowDirection.TOP:
paddingTop -= arrowHeight;
break;
case ArrowDirection.BOTTOM:
paddingBottom -= arrowHeight;
break;
}
if (strokeWidth > 0) {
paddingLeft -= strokeWidth;
paddingRight -= strokeWidth;
paddingTop -= strokeWidth;
paddingBottom -= strokeWidth;
}
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
}

View File

@@ -0,0 +1,33 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import com.mapbox.mapboxsdk.R;
class BubblePopupHelper {
static PopupWindow create(@NonNull Context context, @NonNull BubbleLayout bubbleLayout) {
PopupWindow popupWindow = new PopupWindow(context);
popupWindow.setContentView(bubbleLayout);
popupWindow.setOutsideTouchable(true);
popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
// change background color to transparent
Drawable drawable;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawable = context.getDrawable(R.drawable.mapbox_popup_window_transparent);
} else {
drawable = context.getResources().getDrawable(R.drawable.mapbox_popup_window_transparent);
}
popupWindow.setBackgroundDrawable(drawable);
return popupWindow;
}
}

View File

@@ -133,7 +133,7 @@ public class InfoWindow {
float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
float y = coordinates.y - view.getMeasuredHeight() + offsetY;
if (view instanceof InfoWindowView) {
if (view instanceof BubbleLayout) {
// only apply repositioning/margin for InfoWindowView
Resources resources = mapView.getContext().getResources();
@@ -187,8 +187,7 @@ public class InfoWindow {
}
// Adjust tipView
InfoWindowView infoWindowView = (InfoWindowView) view;
infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
((BubbleLayout) view).setArrowPosition(tipViewMarginLeft);
}
// set anchor popupwindowview
@@ -284,7 +283,7 @@ public class InfoWindow {
if (mapboxMap != null && marker != null && view != null) {
coordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
if (view instanceof InfoWindowView) {
if (view instanceof BubbleLayout) {
view.setX(coordinates.x + viewWidthOffset - markerWidthOffset);
} else {
view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset);

View File

@@ -1,62 +0,0 @@
package com.mapbox.mapboxsdk.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;
import com.mapbox.mapboxsdk.R;
final class InfoWindowTipView extends View {
private Paint mPaint;
private Path mPath;
private int mLineWidth;
public InfoWindowTipView(Context context, AttributeSet attrs) {
super(context, attrs);
mPath = new Path();
mLineWidth = (int) context.getResources().getDimension(R.dimen.mapbox_infowindow_line_width);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(0.0f);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getMeasuredHeight();
int width = getMeasuredWidth();
mPath.rewind();
this.mPaint.setColor(Color.WHITE);
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(0.0f);
this.mPaint.setStyle(Paint.Style.FILL);
mPath.moveTo(0, 0);
mPath.lineTo(width, 0);
mPath.lineTo((width / 2), height);
mPath.lineTo(0, 0);
canvas.drawPath(mPath, this.mPaint);
mPath.rewind();
this.mPaint.setColor(Color.parseColor("#C2C2C2"));
this.mPaint.setAntiAlias(true);
this.mPaint.setStrokeWidth(mLineWidth);
this.mPaint.setStyle(Paint.Style.STROKE);
mPath.moveTo(0, 0);
mPath.lineTo(width / 2, height);
mPath.lineTo(width, 0);
canvas.drawPath(mPath, this.mPaint);
}
}

View File

@@ -1,38 +0,0 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import com.mapbox.mapboxsdk.R;
class InfoWindowView extends RelativeLayout {
private InfoWindowTipView mTipView;
public InfoWindowView(Context context) {
this(context, null);
}
public InfoWindowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context) {
LayoutInflater.from(context).inflate(R.layout.mapbox_infowindow_content, this);
mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
}
void setTipViewMarginLeft(int marginLeft) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
layoutParams.leftMargin = marginLeft;
// This is a bit of a hack but prevents an occasional gap between the InfoWindow
layoutParams.topMargin = (int) getResources().getDimension(R.dimen.mapbox_infowindow_offset);
}
}

View File

@@ -238,7 +238,7 @@ public class Marker extends Annotation {
private InfoWindow getInfoWindow(@NonNull MapView mapView) {
if (infoWindow == null && mapView.getContext() != null) {
infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_view, getMapboxMap());
infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_content, getMapboxMap());
}
return infoWindow;
}