mirror of
https://github.com/ev-map/EVMap.git
synced 2026-04-23 23:57:08 -04:00
improve animation performance
This commit is contained in:
@@ -302,10 +302,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
MarkerOptions()
|
||||
.position(LatLng(charger.coordinates.lat, charger.coordinates.lng))
|
||||
.icon(
|
||||
chargerIconGenerator.getBitmapDescriptor(
|
||||
R.drawable.ic_map_marker_charging,
|
||||
tint
|
||||
)
|
||||
chargerIconGenerator.getBitmapDescriptor(tint)
|
||||
)
|
||||
)
|
||||
animateMarkerAppear(marker, tint, chargerIconGenerator)
|
||||
|
||||
@@ -5,9 +5,9 @@ import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.LruCache
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import com.google.android.gms.maps.model.BitmapDescriptor
|
||||
@@ -40,29 +40,56 @@ class ClusterIconGenerator(context: Context) : IconGenerator(context) {
|
||||
|
||||
|
||||
class ChargerIconGenerator(val context: Context) {
|
||||
data class BitmapData(val id: Int, val tint: Int, val scale: Int, val alpha: Int)
|
||||
data class BitmapData(val tint: Int, val scale: Int, val alpha: Int)
|
||||
|
||||
val cache = hashMapOf<BitmapData, Bitmap>()
|
||||
val cacheSize = 4 * 1024 * 1024; // 4MiB
|
||||
val cache = object : LruCache<BitmapData, Bitmap>(cacheSize) {
|
||||
override fun sizeOf(key: BitmapData, value: Bitmap): Int {
|
||||
return value.byteCount
|
||||
}
|
||||
}
|
||||
val oversize = 1.5f
|
||||
val icon = R.drawable.ic_map_marker_charging
|
||||
|
||||
init {
|
||||
preloadCache()
|
||||
}
|
||||
|
||||
fun preloadCache() {
|
||||
// pre-generates images for scale from 0 to 255 for all possible tint colors
|
||||
val tints = listOf(
|
||||
R.color.charger_100kw,
|
||||
R.color.charger_43kw,
|
||||
R.color.charger_20kw,
|
||||
R.color.charger_11kw,
|
||||
R.color.charger_low
|
||||
)
|
||||
for (tint in tints) {
|
||||
for (scale in 0..20) {
|
||||
val data = BitmapData(tint, scale, 255)
|
||||
cache.put(data, generateBitmap(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBitmapDescriptor(
|
||||
@DrawableRes id: Int,
|
||||
@ColorRes tint: Int,
|
||||
scale: Int = 255,
|
||||
scale: Int = 20,
|
||||
alpha: Int = 255
|
||||
): BitmapDescriptor? {
|
||||
val data = BitmapData(id, tint, scale, alpha)
|
||||
if (cache.containsKey(data)) {
|
||||
return BitmapDescriptorFactory.fromBitmap(cache[data])
|
||||
val data = BitmapData(tint, scale, alpha)
|
||||
val cachedImg = cache[data]
|
||||
return if (cachedImg != null) {
|
||||
BitmapDescriptorFactory.fromBitmap(cachedImg)
|
||||
} else {
|
||||
val bitmap = generateBitmap(data)
|
||||
cache[data] = bitmap
|
||||
return BitmapDescriptorFactory.fromBitmap(bitmap)
|
||||
cache.put(data, bitmap)
|
||||
BitmapDescriptorFactory.fromBitmap(bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateBitmap(data: BitmapData): Bitmap {
|
||||
val vd: Drawable = context.getDrawable(data.id)!!
|
||||
val vd: Drawable = context.getDrawable(icon)!!
|
||||
|
||||
DrawableCompat.setTint(vd, ContextCompat.getColor(context, data.tint));
|
||||
DrawableCompat.setTintMode(vd, PorterDuff.Mode.MULTIPLY);
|
||||
@@ -82,7 +109,7 @@ class ChargerIconGenerator(val context: Context) {
|
||||
)
|
||||
val canvas = Canvas(bm)
|
||||
|
||||
val scale = data.scale / 255f
|
||||
val scale = data.scale / 20f
|
||||
canvas.scale(
|
||||
scale,
|
||||
scale,
|
||||
|
||||
@@ -21,7 +21,7 @@ fun animateMarkerAppear(
|
||||
tint: Int,
|
||||
gen: ChargerIconGenerator
|
||||
) {
|
||||
ValueAnimator.ofInt(0, 255).apply {
|
||||
ValueAnimator.ofInt(0, 20).apply {
|
||||
duration = 250
|
||||
interpolator = LinearOutSlowInInterpolator()
|
||||
addUpdateListener { animationState ->
|
||||
@@ -31,11 +31,7 @@ fun animateMarkerAppear(
|
||||
}
|
||||
val scale = animationState.animatedValue as Int
|
||||
marker.setIcon(
|
||||
gen.getBitmapDescriptor(
|
||||
R.drawable.ic_map_marker_charging,
|
||||
tint,
|
||||
scale = scale
|
||||
)
|
||||
gen.getBitmapDescriptor(tint, scale = scale)
|
||||
)
|
||||
}
|
||||
}.start()
|
||||
@@ -46,7 +42,7 @@ fun animateMarkerDisappear(
|
||||
tint: Int,
|
||||
gen: ChargerIconGenerator
|
||||
) {
|
||||
ValueAnimator.ofInt(255, 0).apply {
|
||||
ValueAnimator.ofInt(20, 0).apply {
|
||||
duration = 200
|
||||
interpolator = FastOutLinearInInterpolator()
|
||||
addUpdateListener { animationState ->
|
||||
@@ -56,11 +52,7 @@ fun animateMarkerDisappear(
|
||||
}
|
||||
val scale = animationState.animatedValue as Int
|
||||
marker.setIcon(
|
||||
gen.getBitmapDescriptor(
|
||||
R.drawable.ic_map_marker_charging,
|
||||
tint,
|
||||
scale = scale
|
||||
)
|
||||
gen.getBitmapDescriptor(tint, scale = scale)
|
||||
)
|
||||
}
|
||||
addListener(onEnd = {
|
||||
|
||||
Reference in New Issue
Block a user