关于使用Android在Google Maps上应用脉冲效果的问题。我们正在尝试在地图上同时存在大约200个脉冲的情况下获得结果。这是我们所指的脉冲效应的一个示例-https://i.stack.imgur.com/ePoL3.gif。您能否建议我们以最好的方法来应用脉冲效果显示并避免任何滞后。
此外,我们感谢您在缩放方面的帮助-您能否根据缩放级别建议显示脉冲效果的最佳方法。
import android.animation.PropertyValuesHolder
import android.animation.ValueAnimator
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.MapView
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.model.*
import com.google.maps.android.data.Feature
import com.google.maps.android.data.Layer
import com.google.maps.android.data.geojson.GeoJsonFeature
import com.google.maps.android.data.geojson.GeoJsonLayer
import com.google.maps.android.data.geojson.GeoJsonPoint
import com.google.maps.android.data.geojson.GeoJsonPointStyle
import kotlinx.android.synthetic.main.activity_maps.*
import org.json.JSONObject
class MapsActivity : AppCompatActivity(), OnMapReadyCallback, View.OnClickListener,
Layer.OnFeatureClickListener {
private lateinit var mapView: MapView
private lateinit var mMap: GoogleMap
private var source: GeoJsonLayer? = null
private var sourcePin: GeoJsonLayer? = null
private var isDayMode = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
mapView = findViewById(R.id.mapview)
mapView.onCreate(savedInstanceState)
change_mode.setOnClickListener(this)
add_markers.setOnClickListener(this)
mapView.getMapAsync(this)
}
override fun onClick(v: View?) {
when (v) {
change_mode -> {
val mapStyle: MapStyleOptions = if (isDayMode) {
isDayMode = false
MapStyleOptions.loadRawResourceStyle(this, R.raw.night_mode)
} else {
isDayMode = true
MapStyleOptions("[]")
}
mMap.setMapStyle(mapStyle)
}
add_markers -> {
mMap.clear()
genListAndSet()
}
}
}
private fun genListAndSet() {
val events = arrayListOf<Event>()
for (i in 0..100) {
val category = when (i) {
in 0..33 -> {
"MUSIC"
}
in 34..68 -> {
"SPORTS"
}
else -> {
"CONCERTS"
}
}
events.add(
Event(
category,
"event_id_$i",
LatLng(
-32.557013 + ((0..10).random() * 0.005),
-56.149056 + ((0..10).random() * 0.005)
)
)
)
}
sourcePin = GeoJsonLayer(mMap, JSONObject())
source = GeoJsonLayer(mMap, JSONObject())
addMarker(events)
}
private fun addMarker(eventsList: List<Event>) {
for (event in eventsList) {
val eventCoord = LatLng(
event.position?.latitude!!,
event.position.longitude
)
val iconPin = BitmapDescriptorFactory.fromBitmap(
ContextCompat.getDrawable(
this,
R.drawable.black_pin_bg
)?.toBitmap()
)
val featurePin = GeoJsonFeature(
GeoJsonPoint(
eventCoord
), event.id, hashMapOf(Pair("category", event.category)), null
)
val stylePin = GeoJsonPointStyle()
stylePin.icon = iconPin
stylePin.isFlat = true
stylePin.setAnchor(0.5f, 0.5f)
featurePin.pointStyle = stylePin
sourcePin?.addFeature(featurePin)
val icon =
BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(
resources,
resources.getIdentifier(
"pin_${
Enums.EventCategories.categoryOf(
event.category!!
)
}", "drawable", packageName
)
)
)
val feature = GeoJsonFeature(
GeoJsonPoint(
eventCoord
), event.id, hashMapOf(Pair("category", event.category)), null
)
val style = GeoJsonPointStyle()
style.icon = icon
feature.pointStyle = style
source?.addFeature(feature)
showRipples(
eventCoord
)
}
sourcePin?.addLayerToMap()
source?.addLayerToMap()
source?.setOnFeatureClickListener(this)
}
override fun onFeatureClick(p0: Feature?) {
println("? ${p0?.id}")
val feature = p0 as GeoJsonFeature
val icon =
BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(
resources,
resources.getIdentifier(
"pin_selected_${
Enums.EventCategories.categoryOf(
feature.getProperty("category")
)
}", "drawable", packageName
)
)
)
val style = GeoJsonPointStyle()
style.icon = icon
feature.pointStyle = style
source?.removeFeature(feature)
source?.addFeature(feature)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-32.557013, -56.149056), 15f))
genListAndSet()
}
private fun showRipples(latLng: LatLng) {
val d = GradientDrawable()
d.shape = GradientDrawable.OVAL
d.setSize(300, 300)
d.setColor(Color.RED)
d.setStroke(0, Color.TRANSPARENT)
val bitmap = Bitmap.createBitmap(
d.intrinsicWidth, d.intrinsicHeight, Bitmap.Config.ARGB_4444
)
// Convert the drawable to bitmap
val canvas = Canvas(bitmap)
d.setBounds(0, 0, canvas.width, canvas.height)
d.draw(canvas)
// Radius of the circle
val radius = 500
// Add the circle to the map
val circle: GroundOverlay = mMap.addGroundOverlay(
GroundOverlayOptions()
.position(latLng, 2 * radius.toFloat()).image(
BitmapDescriptorFactory.fromBitmap(
bitmap
)
)
)
// Prep the animator
val radiusHolder =
PropertyValuesHolder.ofFloat("radius", 0f, radius.toFloat())
val transparencyHolder =
PropertyValuesHolder.ofFloat("transparency", 0f, 1f)
val valueAnimator = ValueAnimator()
valueAnimator.repeatCount = ValueAnimator.INFINITE
valueAnimator.repeatMode = ValueAnimator.RESTART
valueAnimator.setValues(radiusHolder, transparencyHolder)
valueAnimator.duration = DURATION.toLong()
valueAnimator.setEvaluator(FloatEvaluator())
valueAnimator.interpolator = AccelerateDecelerateInterpolator()
valueAnimator.addUpdateListener { animator ->
val animatedRadius =
animator.getAnimatedValue("radius") as Float
val animatedAlpha =
animator.getAnimatedValue("transparency") as Float
circle.setDimensions(animatedRadius * 2)
circle.transparency = animatedAlpha
}
// start the animation
valueAnimator.start()
}
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mapView.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
companion object {
private const val DURATION = 3000
}
}```
Thanks in advance!
[1]: https://i.stack.imgur.com/vkhUi.png