1

我在我目前正在开发的谷歌地图应用程序中使用集群管理器。我的问题是,每当我在 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)
                )
            })

        }
    }





}

4

1 回答 1

0

一个建议是设置一个侦听器,在加载所有集群项目/标记时调用该侦听器,然后稍微更改地图缩放级别。反过来,所有集群项目都将显示在地图上。

zoom = googleMap.getCameraPosition().zoom;
latLng = googleMap.getCameraPosition().target;
newZoom = zoom + 0.0001f;
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,newZoom));

作品!

于 2021-03-21T13:34:04.930 回答