我在我目前正在开发的谷歌地图应用程序中使用集群管理器。我的问题是,每当我在 Android Studio Emulator 上启动应用程序时,集群都不会出现。要使它们出现,您必须放大和缩小几次。从这一点开始,集群本身工作得很好,但集群最初没有出现真的让我很恼火。有没有办法解决这个问题,或者我做错了什么?我尝试过
clusterManager.cluster()
或者
mMap.clear()
但这些都没有帮助我。也许你们中的一个可以帮助我:)
这是我的 MapsActivity 中的代码。我正在使用自定义 clusterRenderer。
package com.example.multimodaltraffic
import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.*
import androidx.appcompat.app.AppCompatActivity
import com.example.multimodaltraffic.api.ApiRequests
import com.example.multimodaltraffic.api.stations.NetworkJson
import com.example.multimodaltraffic.locationMarking.MyClusterRenderer
import com.example.multimodaltraffic.locationMarking.MyItem
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import com.google.maps.android.clustering.ClusterManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import androidx.constraintlayout.widget.ConstraintLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.Retrofit
import retrofit2.awaitResponse
import retrofit2.converter.gson.GsonConverterFactory
import com.example.multimodaltraffic.markerInformationSheet.CustomBottomSheetDialogFragment
import com.example.multimodaltraffic.markerInformationSheet.MyClusterItemClickListener
import com.example.multimodaltraffic.markerInformationSheet.MyClusterClickListener
const val BASE_URL = "https://api.citybik.es"
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
private lateinit var clusterManager: ClusterManager<MyItem?>
private lateinit var myClusterItemClickListener: MyClusterItemClickListener
private lateinit var myClusterClickListener: MyClusterClickListener
private lateinit var mapFragment: SupportMapFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Placeholder for camera start position
val kassel = LatLng(51.313139, 9.465458)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(kassel, 10f))
// Position the map
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.313139, 9.465458), 10f))
// Initialize the manager with the context and the map
// (Activity extends context, so we can pass 'this' in the constructor)
clusterManager = ClusterManager(this, mMap)
// Point the map's listeners at the listeners implemented by the cluster manager
mMap.setOnCameraIdleListener(clusterManager)
mMap.setOnMarkerClickListener(clusterManager)
//use own renderer; allows customizing markers & clusters
clusterManager.renderer = MyClusterRenderer(this, mMap, clusterManager)
myClusterItemClickListener = MyClusterItemClickListener(this, mapFragment, mMap)
myClusterClickListener = MyClusterClickListener(this, mMap)
clusterManager.setOnClusterItemClickListener(myClusterItemClickListener)
clusterManager.setOnClusterClickListener(myClusterClickListener)
// Add cluster items (markers) to the cluster manager
getCurrentData()
}
// Declare a variable for the cluster manager
//used in function getCurrentData()
private fun addItems(network: NetworkJson) {
network.network.stations.forEach {
val station = LatLng(it.latitude, it.longitude)
//Snippet-String is sliced in class MyClusterRenderer in order to get free bikes and empty slots integer!
val offsetItem = MyItem(it.timestamp, it.emptySlots.toString(), it.freeBikes.toString(), it.latitude, it.longitude, it.name, "Free bikes: " + it.freeBikes + "\nEmpty slots: " + it.emptySlots)
clusterManager.addItem(offsetItem)
}
}
// Get data from CityBikes API
private fun getCurrentData() {
var api = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiRequests::class.java)
GlobalScope.launch(Dispatchers.IO) {
try {
val response = api.getNextbikeData().awaitResponse()
if (response.isSuccessful) {
var networks = response.body()!!
networks.networks.forEach {
if (it.location.country == "DE") {
GlobalScope.launch(Dispatchers.IO) {
api = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiRequests::class.java)
val response = api.getStations(it.id).awaitResponse()
if (response.isSuccessful) {
var network = response.body()!!
//loadMapMarkers(network)
addItems(network)
}
}
}
}
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(
applicationContext,
"Seems like something went wrong...",
Toast.LENGTH_SHORT
).show()
}
}
}
}
private fun loadMapMarkers(network: NetworkJson) {
// @TODO Safe marker to update informations
network.network.stations.forEach {
val station = LatLng(it.latitude, it.longitude)
this@MapsActivity.runOnUiThread(Runnable {
mMap.addMarker(MarkerOptions()
.position(station)
.title(it.name)
.snippet("Free bikes: " + it.freeBikes)
)
})
}
}
}