[android] #4396 - UserLocationView improvements
This commit is contained in:
committed by
Tobrun
parent
668405e61f
commit
b3e340ca11
@@ -19,6 +19,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.location.Location;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
@@ -880,6 +881,67 @@ public class MapView extends FrameLayout {
|
||||
throw new TelemetryServiceNotConfiguredException();
|
||||
}
|
||||
|
||||
//
|
||||
// User marker location drawable management
|
||||
//
|
||||
|
||||
/**
|
||||
* Set the user location view default drawable .
|
||||
*/
|
||||
void setUserLocationDrawable(Drawable drawable) {
|
||||
mUserLocationView.setUserLocationDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view default drawable and its shadow.
|
||||
*/
|
||||
void setUserLocationDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mUserLocationView.setUserLocationDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view bearing drawable.
|
||||
*/
|
||||
void setUserLocationBearingDrawable(Drawable drawable) {
|
||||
mUserLocationView.setUserLocationBearingDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view bearing drawable and its shadow.
|
||||
*/
|
||||
void setUserLocationBearingDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mUserLocationView.setUserLocationBearingDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stale user location view drawable.
|
||||
*/
|
||||
void setUserLocationStaleDrawable(Drawable drawable) {
|
||||
mUserLocationView.setUserLocationStaleDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stale user location view drawable and its shadow.
|
||||
*/
|
||||
void setUserLocationStaleDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mUserLocationView.setUserLocationStaleDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the offset of the user location view shadow
|
||||
*/
|
||||
void setUserLocationShadowOffset(int x, int y) {
|
||||
mUserLocationView.setUserLocationShadowOffset(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the accuracy color
|
||||
* @param color int real color (not a @ColorRes)
|
||||
*/
|
||||
void setUserLocationAccuracyColor(int color) {
|
||||
mUserLocationView.setUserLocationAccuracyColor(color);
|
||||
}
|
||||
|
||||
//
|
||||
// Projection
|
||||
//
|
||||
@@ -1648,9 +1710,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// reset tracking modes if gesture occurs
|
||||
if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
|
||||
resetTrackingModes();
|
||||
}
|
||||
resetTrackingModesIfRequired();
|
||||
|
||||
// Fling the map
|
||||
float ease = 0.25f;
|
||||
@@ -1686,10 +1746,9 @@ public class MapView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModes();
|
||||
}
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModesIfRequired();
|
||||
|
||||
|
||||
// Cancel any animation
|
||||
mNativeMapView.cancelTransitions();
|
||||
@@ -1718,10 +1777,8 @@ public class MapView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModes();
|
||||
}
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModesIfRequired();
|
||||
|
||||
mBeginTime = detector.getEventTime();
|
||||
trackGestureEvent(MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY());
|
||||
@@ -1803,10 +1860,8 @@ public class MapView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModes();
|
||||
}
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModesIfRequired();
|
||||
|
||||
mBeginTime = detector.getEventTime();
|
||||
trackGestureEvent(MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY());
|
||||
@@ -1884,10 +1939,8 @@ public class MapView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModes();
|
||||
}
|
||||
// reset tracking modes if gesture occurs
|
||||
resetTrackingModesIfRequired();
|
||||
|
||||
mBeginTime = detector.getEventTime();
|
||||
trackGestureEvent(MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY());
|
||||
@@ -2367,11 +2420,28 @@ public class MapView extends FrameLayout {
|
||||
ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private void resetTrackingModes() {
|
||||
private void resetTrackingModesIfRequired() {
|
||||
TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
|
||||
if (trackingSettings.isDismissLocationTrackingOnGesture()) {
|
||||
resetLocationTrackingMode();
|
||||
}
|
||||
if (trackingSettings.isDismissBearingTrackingOnGesture()) {
|
||||
resetBearingTrackingMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetLocationTrackingMode() {
|
||||
try {
|
||||
TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
|
||||
trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
|
||||
trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
|
||||
} catch (SecurityException ignore) {
|
||||
// User did not accept location permissions
|
||||
}
|
||||
}
|
||||
|
||||
private void resetBearingTrackingMode() {
|
||||
try {
|
||||
setMyBearingTrackingMode(MyBearingTracking.NONE);
|
||||
} catch (SecurityException ignore) {
|
||||
// User did not accept location permissions
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.location.Location;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.FloatRange;
|
||||
@@ -576,6 +577,69 @@ public class MapboxMap {
|
||||
mMapView.setAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view default drawable .
|
||||
*/
|
||||
public void setUserLocationDrawable(Drawable drawable) {
|
||||
mMapView.setUserLocationDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view default drawable and its shadow.
|
||||
*/
|
||||
public void setUserLocationDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mMapView.setUserLocationDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view bearing drawable.
|
||||
*/
|
||||
public void setUserLocationBearingDrawable(Drawable drawable) {
|
||||
mMapView.setUserLocationBearingDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user location view bearing drawable and its shadow.
|
||||
*/
|
||||
public void setUserLocationBearingDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mMapView.setUserLocationBearingDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stale user location view drawable.
|
||||
*/
|
||||
public void setUserLocationStaleDrawable(Drawable drawable) {
|
||||
mMapView.setUserLocationStaleDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stale user location view drawable and its shadow.
|
||||
*/
|
||||
public void setUserLocationStaleDrawable(Drawable drawable, Drawable shadowDrawable) {
|
||||
mMapView.setUserLocationStaleDrawable(drawable, shadowDrawable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the offset of the user location view shadow.
|
||||
*
|
||||
* @param x int x offset in pixels
|
||||
* @param y int y offset in pixels
|
||||
*/
|
||||
public void setUserLocationShadowOffset(int x, int y) {
|
||||
mMapView.setUserLocationShadowOffset(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the accuracy circle (fill and stroke) color of the user location view
|
||||
*
|
||||
* @param color int real color (not a @ColorRes)
|
||||
*/
|
||||
public void setUserLocationAccuracyColor(int color) {
|
||||
mMapView.setUserLocationAccuracyColor(color);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current Mapbox access token used to load map styles and tiles.
|
||||
*
|
||||
|
||||
@@ -14,7 +14,8 @@ public class TrackingSettings {
|
||||
|
||||
private MapView mapView;
|
||||
private UiSettings uiSettings;
|
||||
private boolean dismissTrackingOnGesture = true;
|
||||
private boolean dismissLocationTrackingOnGesture = true;
|
||||
private boolean dismissBearingTrackingOnGesture = true;
|
||||
|
||||
@MyLocationTracking.Mode
|
||||
private int mMyLocationTrackingMode;
|
||||
@@ -44,7 +45,7 @@ public class TrackingSettings {
|
||||
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
mMyLocationTrackingMode = myLocationTrackingMode;
|
||||
mapView.setMyLocationTrackingMode(myLocationTrackingMode);
|
||||
validateGesturesForTrackingModes();
|
||||
validateGesturesForLocationTrackingMode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +80,7 @@ public class TrackingSettings {
|
||||
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
|
||||
mMyBearingTrackingMode = myBearingTrackingMode;
|
||||
mapView.setMyBearingTrackingMode(myBearingTrackingMode);
|
||||
validateGesturesForBearingTrackingMode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +91,7 @@ public class TrackingSettings {
|
||||
* @see MyBearingTracking
|
||||
*/
|
||||
@UiThread
|
||||
@MyLocationTracking.Mode
|
||||
@MyBearingTracking.Mode
|
||||
public int getMyBearingTrackingMode() {
|
||||
return mMyBearingTrackingMode;
|
||||
}
|
||||
@@ -100,7 +102,7 @@ public class TrackingSettings {
|
||||
* @return True to indicate the tracking modes will be dismissed.
|
||||
*/
|
||||
public boolean isDismissTrackingOnGesture() {
|
||||
return dismissTrackingOnGesture;
|
||||
return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,35 +111,67 @@ public class TrackingSettings {
|
||||
* @param dismissTrackingOnGesture True to dismiss the tracking modes.
|
||||
*/
|
||||
public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
|
||||
this.dismissTrackingOnGesture = dismissTrackingOnGesture;
|
||||
dismissLocationTrackingOnGesture = dismissTrackingOnGesture;
|
||||
dismissBearingTrackingOnGesture = dismissTrackingOnGesture;
|
||||
validateGesturesForTrackingModes();
|
||||
}
|
||||
|
||||
private void validateGesturesForTrackingModes() {
|
||||
if (!dismissTrackingOnGesture) {
|
||||
int myLocationTrackingMode = getMyLocationTrackingMode();
|
||||
int myBearingTrackingMode = getMyBearingTrackingMode();
|
||||
validateGesturesForBearingTrackingMode();
|
||||
validateGesturesForLocationTrackingMode();
|
||||
}
|
||||
|
||||
// Enable/disable gestures based on tracking mode
|
||||
private void validateGesturesForLocationTrackingMode() {
|
||||
int myLocationTrackingMode = getMyLocationTrackingMode();
|
||||
|
||||
if (!dismissLocationTrackingOnGesture) {
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
|
||||
uiSettings.setScrollGesturesEnabled(true);
|
||||
uiSettings.setRotateGesturesEnabled(true);
|
||||
} else {
|
||||
uiSettings.setScrollGesturesEnabled(false);
|
||||
uiSettings.setRotateGesturesEnabled((myBearingTrackingMode == MyBearingTracking.NONE));
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
uiSettings.setScrollGesturesEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateGesturesForBearingTrackingMode() {
|
||||
int myBearingTrackingMode = getMyBearingTrackingMode();
|
||||
if (!dismissBearingTrackingOnGesture) {
|
||||
if (myBearingTrackingMode == MyBearingTracking.NONE) {
|
||||
uiSettings.setRotateGesturesEnabled(true);
|
||||
} else {
|
||||
uiSettings.setRotateGesturesEnabled(false);
|
||||
}
|
||||
} else {
|
||||
uiSettings.setRotateGesturesEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDismissLocationTrackingOnGesture(boolean dismissLocationTrackingOnGesture) {
|
||||
this.dismissLocationTrackingOnGesture = dismissLocationTrackingOnGesture;
|
||||
validateGesturesForLocationTrackingMode();
|
||||
}
|
||||
|
||||
public boolean isDismissLocationTrackingOnGesture() {
|
||||
return dismissLocationTrackingOnGesture;
|
||||
}
|
||||
|
||||
public void setDismissBearingTrackingOnGesture(boolean dismissBearingTrackingOnGesture) {
|
||||
this.dismissBearingTrackingOnGesture = dismissBearingTrackingOnGesture;
|
||||
validateGesturesForBearingTrackingMode();
|
||||
}
|
||||
|
||||
public boolean isDismissBearingTrackingOnGesture() {
|
||||
return dismissBearingTrackingOnGesture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if location tracking is disabled
|
||||
*
|
||||
* @return True if location tracking is disabled.
|
||||
*/
|
||||
public boolean isLocationTrackingDisabled() {
|
||||
public boolean isLocationTrackingDisabled(){
|
||||
return mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import android.hardware.SensorManager;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.AttributeSet;
|
||||
@@ -59,17 +60,12 @@ public final class UserLocationView extends View {
|
||||
private Path mAccuracyPath;
|
||||
private RectF mAccuracyBounds;
|
||||
|
||||
private Drawable mUserLocationDrawable;
|
||||
private RectF mUserLocationDrawableBoundsF;
|
||||
private Rect mUserLocationDrawableBounds;
|
||||
private UserLocationViewDrawableHolder mHolder = new UserLocationViewDrawableHolder();
|
||||
private UserLocationViewDrawableHolder mBearingHolder = new UserLocationViewDrawableHolder();
|
||||
private UserLocationViewDrawableHolder mStaleHolder = new UserLocationViewDrawableHolder();
|
||||
|
||||
private Drawable mUserLocationBearingDrawable;
|
||||
private RectF mUserLocationBearingDrawableBoundsF;
|
||||
private Rect mUserLocationBearingDrawableBounds;
|
||||
|
||||
private Drawable mUserLocationStaleDrawable;
|
||||
private RectF mUserLocationStaleDrawableBoundsF;
|
||||
private Rect mUserLocationStaleDrawableBounds;
|
||||
private int mShadowX = 0;
|
||||
private int mShadowY = 0;
|
||||
|
||||
private Rect mDirtyRect;
|
||||
private RectF mDirtyRectF;
|
||||
@@ -137,60 +133,20 @@ public final class UserLocationView extends View {
|
||||
mMarkerScreenPoint = new PointF();
|
||||
mMarkerScreenMatrix = new Matrix();
|
||||
|
||||
mAccuracyPaintFill = new Paint();
|
||||
mAccuracyPaintFill.setAntiAlias(true);
|
||||
mAccuracyPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mAccuracyPaintFill.setStyle(Paint.Style.FILL);
|
||||
mAccuracyPaintFill.setColor(accuracyColor);
|
||||
mAccuracyPaintFill.setAlpha((int) (255 * 0.25f));
|
||||
|
||||
mAccuracyPaintStroke = new Paint();
|
||||
mAccuracyPaintStroke.setAntiAlias(true);
|
||||
mAccuracyPaintStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mAccuracyPaintStroke.setStyle(Paint.Style.STROKE);
|
||||
mAccuracyPaintStroke.setStrokeWidth(0.5f * density);
|
||||
mAccuracyPaintStroke.setColor(accuracyColor);
|
||||
mAccuracyPaintStroke.setAlpha((int) (255 * 0.5f));
|
||||
setUserLocationAccuracyColor(accuracyColor);
|
||||
|
||||
mAccuracyPath = new Path();
|
||||
mAccuracyBounds = new RectF();
|
||||
|
||||
mUserLocationDrawable = ContextCompat.getDrawable(getContext(), R.drawable.my_location);
|
||||
mUserLocationDrawableBounds = new Rect(
|
||||
-mUserLocationDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationDrawableBoundsF = new RectF(
|
||||
-mUserLocationDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationDrawable.setBounds(mUserLocationDrawableBounds);
|
||||
|
||||
mUserLocationBearingDrawable = ContextCompat.getDrawable(getContext(), R.drawable.my_location_bearing);
|
||||
mUserLocationBearingDrawableBounds = new Rect(
|
||||
-mUserLocationBearingDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationBearingDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationBearingDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationBearingDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationBearingDrawableBoundsF = new RectF(
|
||||
-mUserLocationBearingDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationBearingDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationBearingDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationBearingDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationBearingDrawable.setBounds(mUserLocationBearingDrawableBounds);
|
||||
|
||||
mUserLocationStaleDrawable = ContextCompat.getDrawable(getContext(), R.drawable.my_location_stale);
|
||||
mUserLocationStaleDrawableBounds = new Rect(
|
||||
-mUserLocationStaleDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationStaleDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationStaleDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationStaleDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationStaleDrawableBoundsF = new RectF(
|
||||
-mUserLocationStaleDrawable.getIntrinsicWidth() / 2,
|
||||
-mUserLocationStaleDrawable.getIntrinsicHeight() / 2,
|
||||
mUserLocationStaleDrawable.getIntrinsicWidth() / 2,
|
||||
mUserLocationStaleDrawable.getIntrinsicHeight() / 2);
|
||||
mUserLocationStaleDrawable.setBounds(mUserLocationStaleDrawableBounds);
|
||||
setUserLocationDrawable(ContextCompat.getDrawable(getContext(), R.drawable.my_location));
|
||||
setUserLocationBearingDrawable(ContextCompat.getDrawable(getContext(), R.drawable.my_location_bearing));
|
||||
setUserLocationStaleDrawable(ContextCompat.getDrawable(getContext(), R.drawable.my_location_stale));
|
||||
}
|
||||
|
||||
public void setMapboxMap(MapboxMap mapboxMap) {
|
||||
@@ -205,28 +161,93 @@ public final class UserLocationView extends View {
|
||||
if (!mShowMarker) {
|
||||
return;
|
||||
}
|
||||
UserLocationViewDrawableHolder holder = getCurrentDrawableHolder();
|
||||
drawShadow(canvas, holder);
|
||||
draw(canvas, holder);
|
||||
}
|
||||
|
||||
private UserLocationViewDrawableHolder getCurrentDrawableHolder() {
|
||||
UserLocationViewDrawableHolder holder = mShowDirection ? mBearingHolder : mHolder;
|
||||
return mStaleMarker ? mStaleHolder : holder;
|
||||
}
|
||||
|
||||
private void drawShadow(Canvas canvas, UserLocationViewDrawableHolder holder) {
|
||||
if (!holder.hasShadow()) {
|
||||
return;
|
||||
}
|
||||
canvas.save();
|
||||
canvas.translate(mShadowX, mShadowY);
|
||||
canvas.concat(mMarkerScreenMatrix);
|
||||
boolean willDraw = !canvas.quickReject(holder.mShadowBounds, Canvas.EdgeType.AA);
|
||||
|
||||
Drawable dotDrawable = mShowDirection ? mUserLocationBearingDrawable : mUserLocationDrawable;
|
||||
dotDrawable = mStaleMarker ? mUserLocationStaleDrawable : dotDrawable;
|
||||
// IMPORTANT also update in update()
|
||||
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
|
||||
dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
|
||||
if (willDraw) {
|
||||
holder.mShadow.draw(canvas);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
private void draw(Canvas canvas, UserLocationViewDrawableHolder holder) {
|
||||
canvas.save();
|
||||
canvas.concat(mMarkerScreenMatrix);
|
||||
boolean willDraw = true;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN || !canvas.isHardwareAccelerated()) {
|
||||
willDraw = mShowAccuracy && !mStaleMarker && !canvas.quickReject(mAccuracyPath, Canvas.EdgeType.AA);
|
||||
}
|
||||
willDraw |= !canvas.quickReject(dotBounds, Canvas.EdgeType.AA);
|
||||
willDraw |= !canvas.quickReject(holder.mBounds, Canvas.EdgeType.AA);
|
||||
|
||||
if (willDraw) {
|
||||
if (mShowAccuracy && !mStaleMarker) {
|
||||
canvas.drawPath(mAccuracyPath, mAccuracyPaintFill);
|
||||
canvas.drawPath(mAccuracyPath, mAccuracyPaintStroke);
|
||||
}
|
||||
dotDrawable.draw(canvas);
|
||||
holder.mDrawable.draw(canvas);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
|
||||
public void setUserLocationDrawable(@NonNull Drawable drawable) {
|
||||
setUserLocationDrawable(drawable, null);
|
||||
}
|
||||
|
||||
public void setUserLocationDrawable(@NonNull Drawable drawable, @Nullable Drawable shadowDrawable) {
|
||||
mHolder.setDrawable(drawable);
|
||||
mHolder.setShadow(shadowDrawable);
|
||||
update();
|
||||
}
|
||||
|
||||
public void setUserLocationBearingDrawable(@NonNull Drawable drawable) {
|
||||
setUserLocationBearingDrawable(drawable, null);
|
||||
}
|
||||
|
||||
public void setUserLocationBearingDrawable(@NonNull Drawable drawable, @Nullable Drawable shadowDrawable) {
|
||||
mBearingHolder.setDrawable(drawable);
|
||||
mBearingHolder.setShadow(shadowDrawable);
|
||||
update();
|
||||
}
|
||||
|
||||
public void setUserLocationStaleDrawable(@NonNull Drawable drawable) {
|
||||
setUserLocationStaleDrawable(drawable, null);
|
||||
}
|
||||
|
||||
public void setUserLocationStaleDrawable(@NonNull Drawable drawable, @Nullable Drawable shadowDrawable) {
|
||||
mStaleHolder.setDrawable(drawable);
|
||||
mStaleHolder.setShadow(shadowDrawable);
|
||||
update();
|
||||
}
|
||||
|
||||
public void setUserLocationShadowOffset(int x, int y) {
|
||||
mShadowX = x;
|
||||
mShadowY = y;
|
||||
update();
|
||||
}
|
||||
|
||||
public void setUserLocationAccuracyColor(int color) {
|
||||
mAccuracyPaintFill.setColor(color);
|
||||
mAccuracyPaintFill.setAlpha((int) (255 * 0.25f));
|
||||
mAccuracyPaintStroke.setColor(color);
|
||||
mAccuracyPaintStroke.setAlpha((int) (255 * 0.5f));
|
||||
update();
|
||||
}
|
||||
|
||||
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
@@ -329,8 +350,10 @@ public final class UserLocationView extends View {
|
||||
invalidate(mDirtyRect);
|
||||
}
|
||||
|
||||
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
|
||||
dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
|
||||
UserLocationViewDrawableHolder holder = getCurrentDrawableHolder();
|
||||
|
||||
|
||||
RectF dotBounds = holder.mBounds;
|
||||
RectF largerBounds = mShowAccuracy && !mStaleMarker && mAccuracyBounds.contains(dotBounds)
|
||||
? mAccuracyBounds : dotBounds;
|
||||
mMarkerScreenMatrix.mapRect(mDirtyRectF, largerBounds);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.mapbox.mapboxsdk.maps.widgets;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Holder for the UserLocationView drawables.</p>
|
||||
* <p>Holds the drawable and its shadow if set, and manage their initialization.</p>
|
||||
*/
|
||||
class UserLocationViewDrawableHolder {
|
||||
Drawable mDrawable;
|
||||
Drawable mShadow;
|
||||
final RectF mBounds = new RectF();
|
||||
final RectF mShadowBounds = new RectF();
|
||||
|
||||
public UserLocationViewDrawableHolder() {
|
||||
}
|
||||
|
||||
public UserLocationViewDrawableHolder(Drawable drawable, Drawable shadow) {
|
||||
setDrawable(drawable);
|
||||
setShadow(shadow);
|
||||
}
|
||||
|
||||
void setDrawable(@NonNull Drawable drawable) {
|
||||
mDrawable = drawable;
|
||||
setDrawable(mDrawable, mBounds);
|
||||
}
|
||||
|
||||
void setShadow(@Nullable Drawable drawable) {
|
||||
mShadow = drawable;
|
||||
setDrawable(mShadow, mShadowBounds);
|
||||
}
|
||||
|
||||
boolean hasShadow() {
|
||||
return mShadow != null;
|
||||
}
|
||||
|
||||
private static void setDrawable(final @Nullable Drawable drawable, final @NonNull RectF bounds) {
|
||||
if (drawable != null) {
|
||||
int halfWidth = drawable.getIntrinsicWidth() / 2;
|
||||
int halfHeight = drawable.getIntrinsicHeight() / 2;
|
||||
bounds.set(
|
||||
-halfWidth,
|
||||
-halfHeight,
|
||||
halfWidth,
|
||||
halfHeight);
|
||||
drawable.setBounds(new Rect(
|
||||
-halfWidth,
|
||||
-halfHeight,
|
||||
halfWidth,
|
||||
halfHeight));
|
||||
} else {
|
||||
bounds.setEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user