diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index 62e3587a..12aa8a42 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -44,7 +44,10 @@ import net.vonforst.evmap.api.goingelectric.ChargeLocation import net.vonforst.evmap.api.goingelectric.ChargeLocationCluster import net.vonforst.evmap.api.goingelectric.ChargepointListItem import net.vonforst.evmap.databinding.FragmentMapBinding -import net.vonforst.evmap.ui.* +import net.vonforst.evmap.ui.ChargerIconGenerator +import net.vonforst.evmap.ui.ClusterIconGenerator +import net.vonforst.evmap.ui.MarkerAnimator +import net.vonforst.evmap.ui.getMarkerTint import net.vonforst.evmap.viewmodel.GalleryViewModel import net.vonforst.evmap.viewmodel.MapPosition import net.vonforst.evmap.viewmodel.MapViewModel @@ -66,6 +69,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac private lateinit var clusterIconGenerator: ClusterIconGenerator private lateinit var chargerIconGenerator: ChargerIconGenerator + private lateinit var animator: MarkerAnimator override fun onCreateView( inflater: LayoutInflater, @@ -79,6 +83,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext()) clusterIconGenerator = ClusterIconGenerator(requireContext()) chargerIconGenerator = ChargerIconGenerator(requireContext()) + animator = MarkerAnimator(chargerIconGenerator) setHasOptionsMenu(true) postponeEnterTransition() @@ -328,7 +333,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac if (!chargepointIds.contains(it.value.id)) { val tint = getMarkerTint(it.value) if (it.key.isVisible) { - animateMarkerDisappear(it.key, tint, chargerIconGenerator) + animator.animateMarkerDisappear(it.key, tint) } else { it.key.remove() } @@ -348,7 +353,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac chargerIconGenerator.getBitmapDescriptor(tint) ) ) - animateMarkerAppear(marker, tint, chargerIconGenerator) + animator.animateMarkerAppear(marker, tint) marker to charger }.toMap() diff --git a/app/src/main/java/net/vonforst/evmap/ui/MarkerUtils.kt b/app/src/main/java/net/vonforst/evmap/ui/MarkerUtils.kt index 4de3ef07..ea0468b1 100644 --- a/app/src/main/java/net/vonforst/evmap/ui/MarkerUtils.kt +++ b/app/src/main/java/net/vonforst/evmap/ui/MarkerUtils.kt @@ -16,47 +16,65 @@ fun getMarkerTint(charger: ChargeLocation): Int = when { else -> R.color.charger_low } -fun animateMarkerAppear( - marker: Marker, - tint: Int, - gen: ChargerIconGenerator -) { - ValueAnimator.ofInt(0, 20).apply { - duration = 250 - interpolator = LinearOutSlowInInterpolator() - addUpdateListener { animationState -> - if (!marker.isVisible) { - cancel() - return@addUpdateListener - } - val scale = animationState.animatedValue as Int - marker.setIcon( - gen.getBitmapDescriptor(tint, scale = scale) - ) - } - }.start() -} +class MarkerAnimator(val gen: ChargerIconGenerator) { + val animatingMarkers = hashMapOf() -fun animateMarkerDisappear( - marker: Marker, - tint: Int, - gen: ChargerIconGenerator -) { - ValueAnimator.ofInt(20, 0).apply { - duration = 200 - interpolator = FastOutLinearInInterpolator() - addUpdateListener { animationState -> - if (!marker.isVisible) { - cancel() - return@addUpdateListener + fun animateMarkerAppear( + marker: Marker, + tint: Int + ) { + animatingMarkers[marker]?.cancel() + animatingMarkers.remove(marker) + + val anim = ValueAnimator.ofInt(0, 20).apply { + duration = 250 + interpolator = LinearOutSlowInInterpolator() + addUpdateListener { animationState -> + if (!marker.isVisible) { + cancel() + animatingMarkers.remove(marker) + return@addUpdateListener + } + val scale = animationState.animatedValue as Int + marker.setIcon( + gen.getBitmapDescriptor(tint, scale = scale) + ) } - val scale = animationState.animatedValue as Int - marker.setIcon( - gen.getBitmapDescriptor(tint, scale = scale) - ) + addListener(onEnd = { + animatingMarkers.remove(marker) + }) } - addListener(onEnd = { - marker.remove() - }) - }.start() + animatingMarkers[marker] = anim + anim.start() + } + + fun animateMarkerDisappear( + marker: Marker, + tint: Int + ) { + animatingMarkers[marker]?.cancel() + animatingMarkers.remove(marker) + + val anim = ValueAnimator.ofInt(20, 0).apply { + duration = 200 + interpolator = FastOutLinearInInterpolator() + addUpdateListener { animationState -> + if (!marker.isVisible) { + cancel() + animatingMarkers.remove(marker) + return@addUpdateListener + } + val scale = animationState.animatedValue as Int + marker.setIcon( + gen.getBitmapDescriptor(tint, scale = scale) + ) + } + addListener(onEnd = { + animatingMarkers.remove(marker) + marker.remove() + }) + } + animatingMarkers[marker] = anim + anim.start() + } } \ No newline at end of file