[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:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user