Add image support with drawable overload (#13793)

* [android] - add addImage support that takes a Drawable as parameter
This commit is contained in:
Tobrun
2019-01-28 15:06:54 +01:00
committed by GitHub
parent 2a821db754
commit 50018b7574
4 changed files with 121 additions and 2 deletions

View File

@@ -1,17 +1,20 @@
package com.mapbox.mapboxsdk.maps;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import android.util.DisplayMetrics;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
import com.mapbox.mapboxsdk.style.light.Light;
import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -298,6 +301,20 @@ public class Style {
addImage(name, image, false);
}
/**
* Adds an drawable to be converted into a bitmap to be used in the map's style
*
* @param name the name of the image
* @param drawable the drawable instance to convert
*/
public void addImage(@NonNull String name, @NonNull Drawable drawable) {
Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(drawable);
if (bitmap == null) {
throw new IllegalArgumentException("Provided drawable couldn't be converted to a Bitmap.");
}
addImage(name, bitmap, false);
}
/**
* Adds an image to be used in the map's style
*
@@ -312,6 +329,8 @@ public class Style {
/**
* Adds an images to be used in the map's style.
*
* @param images the map of images to add
*/
public void addImages(@NonNull HashMap<String, Bitmap> images) {
addImages(images, false);
@@ -319,6 +338,9 @@ public class Style {
/**
* Adds an images to be used in the map's style.
*
* @param images the map of images to add
* @param sdf the flag indicating image is an SDF or template image
*/
public void addImages(@NonNull HashMap<String, Bitmap> images, boolean sdf) {
validateState("addImages");
@@ -630,6 +652,22 @@ public class Style {
return this;
}
/**
* Will add the drawable as image when the map style has loaded.
*
* @param id the id for the image
* @param drawable the drawable to be converted and added
* @return this
*/
@NonNull
public Builder withImage(@NonNull String id, @NonNull Drawable drawable) {
Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(drawable);
if (bitmap == null) {
throw new IllegalArgumentException("Provided drawable couldn't be converted to a Bitmap.");
}
return this.withImage(id, bitmap, false);
}
/**
* Will add the image when the map style has loaded.
*
@@ -642,11 +680,29 @@ public class Style {
return this.withImage(id, image, false);
}
/**
* Will add the drawable as image when the map style has loaded.
*
* @param id the id for the image
* @param drawable the drawable to be converted and added
* @param sdf the flag indicating image is an SDF or template image
* @return this
*/
@NonNull
public Builder withImage(@NonNull String id, @NonNull Drawable drawable, boolean sdf) {
Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(drawable);
if (bitmap == null) {
throw new IllegalArgumentException("Provided drawable couldn't be converted to a Bitmap.");
}
return this.withImage(id, bitmap, sdf);
}
/**
* Will add the image when the map style has loaded.
*
* @param id the id for the image
* @param image the image to be added
* @param sdf the flag indicating image is an SDF or template image
* @return this
*/
@NonNull

View File

@@ -8,9 +8,12 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.view.View;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Utility class for creating bitmaps
@@ -121,4 +124,23 @@ public class BitmapUtils {
return new BitmapDrawable(context.getResources(), compass);
}
/**
* Validates if the bytes of a bitmap matches another
*
* @param bitmap the bitmap to be compared against
* @param other the bitmap to compare with
* @return true if equal
*/
@VisibleForTesting
public static boolean equals(Bitmap bitmap, Bitmap other) {
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getHeight() * bitmap.getRowBytes());
bitmap.copyPixelsToBuffer(buffer);
ByteBuffer bufferOther = ByteBuffer.allocate(other.getHeight() * other.getRowBytes());
other.copyPixelsToBuffer(bufferOther);
return Arrays.equals(buffer.array(), bufferOther.array());
}
}

View File

@@ -1,11 +1,14 @@
package com.mapbox.mapboxsdk.maps
import android.graphics.Bitmap
import android.graphics.drawable.ShapeDrawable
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
import com.mapbox.mapboxsdk.style.layers.TransitionOptions
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
import com.mapbox.mapboxsdk.utils.BitmapUtils
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@@ -95,6 +98,21 @@ class StyleBuilderTest {
assertEquals(true, builder.images[0].sdf)
}
@Test
fun testWithImageDrawable() {
val drawable = ShapeDrawable()
drawable.intrinsicWidth = 1
drawable.intrinsicHeight = 1
val builder = Style.Builder()
builder.withImage("id", drawable, true)
assertTrue(BitmapUtils.equals(
BitmapUtils.getBitmapFromDrawable(drawable)!!,
builder.images[0].bitmap)
)
assertEquals("id", builder.images[0].id)
assertEquals(true, builder.images[0].sdf)
}
@Test
fun testWithTransitionOptions() {
val transitionOptions = TransitionOptions(100, 200)

View File

@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.maps
import android.graphics.Bitmap
import android.graphics.drawable.ShapeDrawable
import com.mapbox.mapboxsdk.constants.MapboxConstants
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
import com.mapbox.mapboxsdk.style.layers.TransitionOptions
@@ -14,7 +15,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import java.lang.IllegalStateException
@RunWith(RobolectricTestRunner::class)
class StyleTest {
@@ -277,4 +277,27 @@ class StyleTest {
style!!.addLayer(mockk<SymbolLayer>())
}
}
@Test
fun testAddImage() {
val bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
val builder = Style.Builder().fromUrl(Style.SATELLITE).withImage("id", bitmap)
mapboxMap.setStyle(builder)
verify(exactly = 1) { nativeMapView.styleUrl = Style.SATELLITE }
verify(exactly = 0) { nativeMapView.addImages(any()) }
mapboxMap.notifyStyleLoaded()
verify(exactly = 1) { nativeMapView.addImages(any()) }
}
@Test
fun testAddDrawable() {
val drawable = ShapeDrawable()
drawable.intrinsicHeight = 10
drawable.intrinsicWidth = 10
val builder = Style.Builder().fromUrl(Style.SATELLITE).withImage("id", drawable)
mapboxMap.setStyle(builder)
verify(exactly = 1) { nativeMapView.styleUrl = Style.SATELLITE }
verify(exactly = 0) { nativeMapView.addImages(any()) }
mapboxMap.notifyStyleLoaded()
verify(exactly = 1) { nativeMapView.addImages(any()) }
}
}