>() {
+ {
+ add(new Pair<>(4, 2));
+ add(new Pair<>(6, 2));
+ add(new Pair<>(10, 2));
+ add(new Pair<>(20, 2));
+ add(new Pair<>(30, 2));
+ add(new Pair<>(50, 2));
+ add(new Pair<>(75, 3));
+ add(new Pair<>(100, 2));
+ add(new Pair<>(200, 2));
+ add(new Pair<>(300, 3));
+ add(new Pair<>(400, 2));
+ add(new Pair<>(600, 3));
+ add(new Pair<>(800, 2));
+ add(new Pair<>(1000, 2));
+ add(new Pair<>((int) (0.25f * FEET_PER_MILE), 2));
+ add(new Pair<>((int) (0.5f * FEET_PER_MILE), 2));
+ add(new Pair<>(FEET_PER_MILE, 2));
+ add(new Pair<>(2 * FEET_PER_MILE, 2));
+ add(new Pair<>(3 * FEET_PER_MILE, 3));
+ add(new Pair<>(4 * FEET_PER_MILE, 2));
+ add(new Pair<>(8 * FEET_PER_MILE, 2));
+ add(new Pair<>(12 * FEET_PER_MILE, 2));
+ add(new Pair<>(15 * FEET_PER_MILE, 3));
+ add(new Pair<>(20 * FEET_PER_MILE, 2));
+ add(new Pair<>(30 * FEET_PER_MILE, 3));
+ add(new Pair<>(40 * FEET_PER_MILE, 2));
+ add(new Pair<>(80 * FEET_PER_MILE, 2));
+ add(new Pair<>(120 * FEET_PER_MILE, 2));
+ add(new Pair<>(200 * FEET_PER_MILE, 2));
+ add(new Pair<>(300 * FEET_PER_MILE, 3));
+ add(new Pair<>(400 * FEET_PER_MILE, 2));
+ }
+ };
+}
diff --git a/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarOptions.java b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarOptions.java
new file mode 100644
index 000000000..c4a70c9a2
--- /dev/null
+++ b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarOptions.java
@@ -0,0 +1,297 @@
+package com.mapbox.pluginscalebar;
+
+import android.content.Context;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DimenRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.content.ContextCompat;
+
+import java.util.Locale;
+
+/**
+ * Builder class from which a scale bar is created.
+ */
+public class ScaleBarOptions {
+ public static final int REFRESH_INTERVAL_DEFAULT = 15;
+
+ private final Context context;
+ private int refreshInterval;
+ private int textColor;
+ private int primaryColor;
+ private int secondaryColor;
+ private float marginTop;
+ private float marginLeft;
+ private float textBarMargin;
+ private float barHeight;
+ private float borderWidth;
+ private float textSize;
+ private boolean isMetricUnit;
+
+ public ScaleBarOptions(@NonNull Context context) {
+ this.context = context;
+ refreshInterval = REFRESH_INTERVAL_DEFAULT;
+ setBarHeight(R.dimen.mapbox_scale_bar_height);
+ setBorderWidth(R.dimen.mapbox_scale_bar_border_width);
+ setTextSize(R.dimen.mapbox_scale_bar_text_size);
+ setMarginTop(R.dimen.mapbox_scale_bar_margin_top);
+ setMarginLeft(R.dimen.mapbox_scale_bar_margin_left);
+ setTextBarMargin(R.dimen.mapbox_scale_bar_text_margin);
+ isMetricUnit = LocaleUnitResolver.isMetricSystem();
+ setTextColor(android.R.color.black);
+ setPrimaryColor(android.R.color.black);
+ setSecondaryColor(android.R.color.white);
+ }
+
+ /**
+ * Build a scale bar widget instance with current option settings.
+ *
+ * @return The built ScaleBarWidget instance.
+ */
+ ScaleBarWidget build() {
+ ScaleBarWidget scaleBarWidget = new ScaleBarWidget(context);
+ scaleBarWidget.setBarHeight(barHeight);
+ scaleBarWidget.setBorderWidth(borderWidth);
+ scaleBarWidget.setMarginLeft(marginLeft);
+ scaleBarWidget.setMarginTop(marginTop);
+ scaleBarWidget.setTextBarMargin(textBarMargin);
+ scaleBarWidget.setMetricUnit(isMetricUnit);
+ scaleBarWidget.setRefreshInterval(refreshInterval);
+ scaleBarWidget.setPrimaryColor(primaryColor);
+ scaleBarWidget.setSecondaryColor(secondaryColor);
+ scaleBarWidget.setTextColor(textColor);
+ scaleBarWidget.setTextSize(textSize);
+ return scaleBarWidget;
+ }
+
+ /**
+ * Set plugin's minimum refresh interval,
+ * default value is {@link #REFRESH_INTERVAL_DEFAULT}.
+ *
+ * @param refreshInterval the min refresh interval, in millisecond.
+ * @return this
+ */
+ public ScaleBarOptions setRefreshInterval(int refreshInterval) {
+ this.refreshInterval = refreshInterval;
+ return this;
+ }
+
+ /**
+ * Set the text color on scale bar,
+ * default value is android.R.color.black.
+ *
+ * @param textColor the text color on scale bar.
+ * @return this.
+ */
+ public ScaleBarOptions setTextColor(@ColorRes int textColor) {
+ this.textColor = ContextCompat.getColor(context, textColor);
+ return this;
+ }
+
+ /**
+ * Set the primary color of the scale bar, will be used to draw odd index blocks,
+ * default value is android.R.color.black.
+ *
+ * @param primaryColor the primary color of the scale bar.
+ * @return this.
+ */
+ public ScaleBarOptions setPrimaryColor(@ColorRes int primaryColor) {
+ this.primaryColor = ContextCompat.getColor(context, primaryColor);
+ return this;
+ }
+
+ /**
+ * Set the secondary color of the scale bar, will be used to draw even index blocks,
+ * default value is android.R.color.white.
+ *
+ * @param secondaryColor the secondaryColor color of the scale bar.
+ * @return this.
+ */
+ public ScaleBarOptions setSecondaryColor(@ColorRes int secondaryColor) {
+ this.secondaryColor = ContextCompat.getColor(context, secondaryColor);
+ return this;
+ }
+
+ /**
+ * Set the margin between scale bar and the top of mapView.
+ *
+ * @param marginTop the margin between scale bar and the top of mapView, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setMarginTop(float marginTop) {
+ this.marginTop = marginTop;
+ return this;
+ }
+
+ /**
+ * Set the margin between scale bar and the top of mapView.
+ *
+ * @param marginTop the margin between scale bar and the top of mapView, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setMarginTop(@DimenRes int marginTop) {
+ this.marginTop = context.getResources().getDimension(marginTop);
+ return this;
+ }
+
+ /**
+ * Set the height for blocks in scale bar.
+ *
+ * @param barHeight the height for blocks in scale bar, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setBarHeight(float barHeight) {
+ this.barHeight = barHeight;
+ return this;
+ }
+
+ /**
+ * Set the height for blocks in scale bar.
+ *
+ * @param barHeight the height for blocks in scale bar, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setBarHeight(@DimenRes int barHeight) {
+ this.barHeight = context.getResources().getDimension(barHeight);
+ return this;
+ }
+
+ /**
+ * Set the border width in scale bar.
+ *
+ * @param borderWidth the border width in scale bar, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setBorderWidth(float borderWidth) {
+ this.borderWidth = borderWidth;
+ return this;
+ }
+
+ /**
+ * Set the border width in scale bar.
+ *
+ * @param borderWidth the border width in scale bar, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setBorderWidth(@DimenRes int borderWidth) {
+ this.borderWidth = context.getResources().getDimension(borderWidth);
+ return this;
+ }
+
+ /**
+ * Set the text size of scale bar.
+ *
+ * @param textSize the text size of scale bar, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setTextSize(float textSize) {
+ this.textSize = textSize;
+ return this;
+ }
+
+ /**
+ * Set the text size of scale bar.
+ *
+ * @param textSize the text size of scale bar, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setTextSize(@DimenRes int textSize) {
+ this.textSize = context.getResources().getDimension(textSize);
+ return this;
+ }
+
+ /**
+ * Set whether to use metric unit or not. The default value is depends on settings of device.
+ *
+ * @param metricUnit whether to use metric unit or not.
+ * @return this.
+ */
+ public ScaleBarOptions setMetricUnit(boolean metricUnit) {
+ isMetricUnit = metricUnit;
+ return this;
+ }
+
+ /**
+ * Set the left margin between scale bar and mapView.
+ *
+ * @param marginLeft the left margin between scale bar and mapView, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setMarginLeft(float marginLeft) {
+ this.marginLeft = marginLeft;
+ return this;
+ }
+
+ /**
+ * Set the left margin between scale bar and mapView.
+ *
+ * @param marginLeft the left margin between scale bar and mapView, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setMarginLeft(@DimenRes int marginLeft) {
+ this.marginLeft = context.getResources().getDimension(marginLeft);
+ return this;
+ }
+
+ /**
+ * Set the margin between text and blocks inside scale bar.
+ *
+ * @param textBarMargin the margin between text and blocks inside scale bar, in pixel.
+ * @return this.
+ */
+ public ScaleBarOptions setTextBarMargin(float textBarMargin) {
+ this.textBarMargin = textBarMargin;
+ return this;
+ }
+
+ /**
+ * Set the margin between text and blocks inside scale bar.
+ *
+ * @param textBarMargin the margin between text and blocks inside scale bar, in dp.
+ * @return this.
+ */
+ public ScaleBarOptions setTextBarMargin(@DimenRes int textBarMargin) {
+ this.textBarMargin = context.getResources().getDimension(textBarMargin);
+ return this;
+ }
+
+ /**
+ * Helper class to determine the user measuring system.
+ *
+ * Currently supports differentiating between metric vs imperial system.
+ *
+ *
+ * Depends on {@link Locale#getDefault()} which returns the locale used at application startup.
+ *
+ */
+ @VisibleForTesting
+ public static class LocaleUnitResolver {
+
+ /**
+ * Returns true if the user is in a country using the metric system.
+ *
+ * @return true if user country is using metric, false if imperial
+ */
+ public static boolean isMetricSystem() {
+ String countryCode = Locale.getDefault().getCountry().toUpperCase();
+ switch (countryCode) {
+ case ImperialCountryCode.US:
+ case ImperialCountryCode.LIBERIA:
+ case ImperialCountryCode.MYANMAR:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Data class containing uppercase country codes for countries using the imperial system.
+ */
+ static class ImperialCountryCode {
+ static final String US = "US";
+ static final String MYANMAR = "MM";
+ static final String LIBERIA = "LR";
+ }
+ }
+
+}
diff --git a/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarPlugin.java b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarPlugin.java
new file mode 100644
index 000000000..3af4ff3a0
--- /dev/null
+++ b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarPlugin.java
@@ -0,0 +1,92 @@
+package com.mapbox.pluginscalebar;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Projection;
+
+/**
+ * Plugin class that shows a scale bar on MapView and changes the scale corresponding to the MapView's scale.
+ */
+public class ScaleBarPlugin {
+ private final MapView mapView;
+ private final MapboxMap mapboxMap;
+ private final Projection projection;
+ private boolean enabled = true;
+ private ScaleBarWidget scaleBarWidget;
+
+ private final MapboxMap.OnCameraMoveListener cameraMoveListener = new MapboxMap.OnCameraMoveListener() {
+ @Override
+ public void onCameraMove() {
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ double metersPerPixel = projection.getMetersPerPixelAtLatitude(cameraPosition.target.getLatitude());
+ scaleBarWidget.setDistancePerPixel(projection.getMetersPerPixelAtLatitude(metersPerPixel));
+ }
+ };
+
+ public ScaleBarPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap) {
+ this.mapView = mapView;
+ this.mapboxMap = mapboxMap;
+ this.projection = mapboxMap.getProjection();
+ }
+
+ /**
+ * Create a scale bar widget on mapView.
+ *
+ * @param option The scale bar widget options that used to build scale bar widget.
+ * @return The created ScaleBarWidget instance.
+ */
+ public ScaleBarWidget create(@NonNull ScaleBarOptions option) {
+ if (scaleBarWidget != null) {
+ mapView.removeView(scaleBarWidget);
+ }
+ scaleBarWidget = option.build();
+ scaleBarWidget.setMapViewWidth(mapView.getWidth());
+ mapboxMap.addOnCameraMoveListener(cameraMoveListener);
+ mapView.addView(scaleBarWidget);
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ double metersPerPixel = projection.getMetersPerPixelAtLatitude(cameraPosition.target.getLatitude());
+ scaleBarWidget.setDistancePerPixel(projection.getMetersPerPixelAtLatitude(metersPerPixel));
+ return scaleBarWidget;
+ }
+
+ /**
+ * Returns true if the scale plugin is currently enabled and visible.
+ *
+ * @return true if enabled, false otherwise
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Toggles the scale plugin state.
+ *
+ * If the scale plugin wasn't enabled, a {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener}
+ * will be added to the {@link MapView} to listen to scale change events to update the state of this plugin. If the
+ * plugin was enabled the {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener}
+ * will be removed from the map.
+ *
+ */
+ @UiThread
+ public void setEnabled(boolean enabled) {
+ if (this.enabled == enabled) {
+ // already in correct state
+ return;
+ }
+ this.enabled = enabled;
+ if (scaleBarWidget != null) {
+ scaleBarWidget.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ }
+ if (enabled) {
+ mapboxMap.addOnCameraMoveListener(cameraMoveListener);
+ } else {
+ mapboxMap.removeOnCameraMoveListener(cameraMoveListener);
+ }
+ }
+
+}
diff --git a/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarWidget.java b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarWidget.java
new file mode 100644
index 000000000..b8d350b76
--- /dev/null
+++ b/plugin-scalebar/src/main/java/com/mapbox/pluginscalebar/ScaleBarWidget.java
@@ -0,0 +1,362 @@
+package com.mapbox.pluginscalebar;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Handler;
+import android.os.Message;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.util.Pair;
+import android.view.View;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * The scale widget is a visual representation of the scale bar plugin.
+ */
+public class ScaleBarWidget extends View {
+ private static int MSG_WHAT = 0;
+ private final Paint textPaint = new Paint();
+ private final Paint barPaint = new Paint();
+ private int refreshInterval;
+ private int textColor;
+ private int primaryColor;
+ private int secondaryColor;
+ private int mapViewWidth;
+ private float marginLeft;
+ private float marginTop;
+ private float textBarMargin;
+ private float maxBarWidth;
+ private float barHeight;
+ private float borderWidth;
+ private float textSize;
+ private double distancePerPixel;
+ private boolean isMetricUnit;
+ private ArrayList> scaleTable;
+ private String unit;
+ private final RefreshHandler refreshHandler;
+
+ ScaleBarWidget(@NonNull Context context) {
+ super(context);
+ textPaint.setAntiAlias(true);
+ textPaint.setTextAlign(Paint.Align.CENTER);
+ barPaint.setAntiAlias(true);
+ refreshHandler = new RefreshHandler(this);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (distancePerPixel <= 0) {
+ return;
+ }
+ double maxDistance = mapViewWidth * distancePerPixel / 2;
+ Pair pair = scaleTable.get(0);
+ for (int i = 1; i < scaleTable.size(); i++) {
+ pair = scaleTable.get(i);
+ if (pair.first > maxDistance) {
+ //use the last scale here, otherwise the scale will be too large
+ pair = scaleTable.get(i - 1);
+ break;
+ }
+ }
+
+ int unitDistance = pair.first / pair.second;
+ float unitBarWidth = maxBarWidth / 2f;
+ if (unitDistance == 0) {
+ unitDistance = 1;
+ } else {
+ unitBarWidth = (float) (unitDistance / distancePerPixel);
+ }
+ //Drawing the surrounding borders
+ barPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+ barPaint.setColor(secondaryColor);
+
+ canvas.drawRect(marginLeft - borderWidth * 2,
+ textBarMargin + textSize + marginTop - borderWidth * 2,
+ marginLeft + unitBarWidth * pair.second + borderWidth * 2,
+ textBarMargin + textSize + marginTop + barHeight + borderWidth * 2,
+ barPaint);
+ barPaint.setColor(primaryColor);
+ canvas.drawRect(marginLeft - borderWidth,
+ textBarMargin + textSize + marginTop - borderWidth,
+ marginLeft + unitBarWidth * pair.second + borderWidth,
+ textBarMargin + textSize + marginTop + barHeight + borderWidth,
+ barPaint);
+
+ //Drawing the fill
+ barPaint.setStyle(Paint.Style.FILL);
+ int i = 0;
+ for (; i < pair.second; i++) {
+ barPaint.setColor(i % 2 == 0 ? primaryColor : secondaryColor);
+ String text = i == 0 ? String.valueOf(unitDistance * i) : unitDistance * i + unit;
+ canvas.drawText(text,
+ marginLeft + unitBarWidth * i,
+ textSize + marginTop,
+ textPaint);
+ canvas.drawRect(marginLeft + unitBarWidth * i,
+ textBarMargin + textSize + marginTop,
+ marginLeft + unitBarWidth * (1 + i),
+ textBarMargin + textSize + marginTop + barHeight,
+ barPaint);
+ }
+ canvas.drawText(unitDistance * i + unit,
+ marginLeft + unitBarWidth * i,
+ textSize + marginTop,
+ textPaint);
+ }
+
+ /**
+ * Update the scale when mapView's scale has changed.
+ *
+ * @param metersPerPixel how many meters in each pixel.
+ */
+ void setDistancePerPixel(double metersPerPixel) {
+ this.distancePerPixel = isMetricUnit ? metersPerPixel : metersPerPixel * ScaleBarConstants.FEET_PER_METER;
+ if (!refreshHandler.hasMessages(MSG_WHAT)) {
+ refreshHandler.sendEmptyMessageDelayed(MSG_WHAT, refreshInterval);
+ }
+ }
+
+ /**
+ * Get plugin's minimum refresh interval, in millisecond.
+ *
+ * @return refresh duration
+ */
+ public int getRefreshInterval() {
+ return refreshInterval;
+ }
+
+ /**
+ * Set plugin's minimum refresh interval, in millisecond.
+ *
+ * @param refreshInterval the refresh duration.
+ */
+ public void setRefreshInterval(int refreshInterval) {
+ this.refreshInterval = refreshInterval;
+ }
+
+ /**
+ * Get the margin between text and blocks.
+ *
+ * @return margin between text and blocks, in pixel.
+ */
+ public float getTextBarMargin() {
+ return textBarMargin;
+ }
+
+ /**
+ * Set the margin between text and blocks inside scale bar.
+ *
+ * @param textBarMargin the margin between text and blocks inside scale bar, in pixel.
+ */
+ public void setTextBarMargin(float textBarMargin) {
+ this.textBarMargin = textBarMargin;
+ }
+
+ /**
+ * Get the left margin between scale bar and mapView.
+ *
+ * @return the left margin between scale bar and mapView, in pixel
+ */
+ public float getMarginLeft() {
+ return marginLeft;
+ }
+
+ /**
+ * Set the left margin between scale bar and mapView.
+ *
+ * @param marginLeft the left margin between scale bar and mapView, in pixel.
+ */
+ public void setMarginLeft(float marginLeft) {
+ this.marginLeft = marginLeft;
+ maxBarWidth = mapViewWidth / 2f - marginLeft;
+ }
+
+ /**
+ * Get the bar height for blocks.
+ *
+ * @return the height for blocks in scale bar, in pixel.
+ */
+ public float getBarHeight() {
+ return barHeight;
+ }
+
+ /**
+ * Set the height for blocks in scale bar.
+ *
+ * @param barHeight the height for blocks in scale bar, in pixel.
+ */
+ public void setBarHeight(float barHeight) {
+ this.barHeight = barHeight;
+ }
+
+ /**
+ * Get the margin between scale bar and the top of mapView,
+ *
+ * @return the margin between scale bar and the top of mapView, in pixel.
+ */
+ public float getMarginTop() {
+ return marginTop;
+ }
+
+ /**
+ * Set the margin between scale bar and the top of mapView。
+ *
+ * @param marginTop the margin between scale bar and the top of mapView, in pixel.
+ */
+ public void setMarginTop(float marginTop) {
+ this.marginTop = marginTop;
+ }
+
+ /**
+ * Get the border width in scale bar.
+ *
+ * @return the border width in scale bar, in pixel
+ */
+ public float getBorderWidth() {
+ return borderWidth;
+ }
+
+ /**
+ * Set the border width in scale bar.
+ *
+ * @param borderWidth the border width in scale bar, in pixel.
+ */
+ public void setBorderWidth(float borderWidth) {
+ this.borderWidth = borderWidth;
+ }
+
+ /**
+ * Get the text size of scale bar.
+ *
+ * @return the text size of scale bar, in pixel.
+ */
+ public float getTextSize() {
+ return textSize;
+ }
+
+ /**
+ * Set the text size of scale bar.
+ *
+ * @param textSize the text size of scale bar, in pixel.
+ */
+ public void setTextSize(float textSize) {
+ this.textSize = textSize;
+ textPaint.setTextSize(textSize);
+ }
+
+ /**
+ * Get the current setting for metrix unit.
+ *
+ * @return true if using metrix unit, otherwise false.
+ */
+ public boolean isMetricUnit() {
+ return isMetricUnit;
+ }
+
+ /**
+ * Set whether to use metric unit or not.
+ *
+ * @param metricUnit whether to use metric unit or not.
+ */
+ public void setMetricUnit(boolean metricUnit) {
+ isMetricUnit = metricUnit;
+ scaleTable = isMetricUnit ? ScaleBarConstants.metricTable : ScaleBarConstants.imperialTable;
+ unit = isMetricUnit ? ScaleBarConstants.METER_UNIT : ScaleBarConstants.FEET_UNIT;
+ }
+
+ /**
+ * Get the color for text.
+ *
+ * @return the color for text.
+ */
+ public int getTextColor() {
+ return textColor;
+ }
+
+ /**
+ * Set the text color on scale bar,
+ *
+ * @param textColor the text color on scale bar.
+ */
+ public void setTextColor(@ColorInt int textColor) {
+ this.textColor = textColor;
+ textPaint.setColor(textColor);
+ }
+
+ /**
+ * Get the primary color of the scale bar.
+ *
+ * @return the primary color of the scale bar.
+ */
+ public int getPrimaryColor() {
+ return primaryColor;
+ }
+
+ /**
+ * Set the primary color of the scale bar, will be used to draw odd index blocks,
+ *
+ * @param primaryColor the primary color of the scale bar, in pixel.
+ */
+ public void setPrimaryColor(@ColorInt int primaryColor) {
+ this.primaryColor = primaryColor;
+ }
+
+ /**
+ * Get the secondary color of the scale bar.
+ *
+ * @return the secondary color of the scale bar.
+ */
+ public int getSecondaryColor() {
+ return secondaryColor;
+ }
+
+ /**
+ * Set the secondary color of the scale bar, will be used to draw even index blocks,
+ *
+ * @param secondaryColor the secondaryColor color of the scale bar, in pixel.
+ */
+ public void setSecondaryColor(@ColorInt int secondaryColor) {
+ this.secondaryColor = secondaryColor;
+ }
+
+ /**
+ * Get the width of current mapView.
+ *
+ * @return the width of current mapView.
+ */
+ public int getMapViewWidth() {
+ return mapViewWidth;
+ }
+
+ /**
+ * Set the width of current mapView.
+ *
+ * @param mapViewWidth mapView's width in pixel.
+ */
+ void setMapViewWidth(int mapViewWidth) {
+ this.mapViewWidth = mapViewWidth;
+ maxBarWidth = mapViewWidth / 2f - marginLeft;
+ }
+
+ /**
+ * Handler class to limit the refresh frequent.
+ */
+ private static class RefreshHandler extends Handler {
+ WeakReference scaleBarWidgetWeakReference;
+
+ RefreshHandler(ScaleBarWidget scaleBarWidget) {
+ scaleBarWidgetWeakReference = new WeakReference<>(scaleBarWidget);
+ }
+
+ public void handleMessage(Message msg) {
+ ScaleBarWidget scaleBarWidget = scaleBarWidgetWeakReference.get();
+ if (msg.what == MSG_WHAT && scaleBarWidget != null) {
+ scaleBarWidget.invalidate();
+ }
+ }
+ }
+
+}
diff --git a/plugin-scalebar/src/main/res/values/dimens.xml b/plugin-scalebar/src/main/res/values/dimens.xml
new file mode 100644
index 000000000..5f56acb7c
--- /dev/null
+++ b/plugin-scalebar/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 8dp
+ 10dp
+ 2dp
+ 8dp
+ 1dp
+ 4dp
+
diff --git a/settings.gradle b/settings.gradle
index e29d567ac..07e316702 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -6,4 +6,5 @@ include ':plugin-offline'
include ':plugin-localization'
include ':plugin-annotation'
include ':plugin-markerview'
-include ':ktx-mapbox-maps'
\ No newline at end of file
+include ':ktx-mapbox-maps'
+include ':plugin-scalebar'
\ No newline at end of file