2

在本教程Introduction to Google Maps API for Android with Kotlin的帮助下,我在 kotlin 中使用谷歌地图。在本教程中展示了如何在位置更新后添加标记但是当它更新时,以前的位置仍然有一个标记并且一次又一次地添加。此代码中没有 Marker 对象,我想保留首先添加的标记,然后移动它。我怎样才能做到这一点?谢谢

 class MapsActivity : AppCompatActivity(), OnMapReadyCallback,
    GoogleMap.OnMarkerClickListener {

private lateinit var map: GoogleMap
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var lastLocation: Location

private lateinit var locationCallback: LocationCallback
private lateinit var locationRequest: LocationRequest
private var locationUpdateState = false

companion object {
    private const val LOCATION_PERMISSION_REQUEST_CODE = 1
    private const val REQUEST_CHECK_SETTINGS = 2
    private const val PLACE_PICKER_REQUEST = 3
}

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.
    val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
    mapFragment.getMapAsync(this)

    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

    locationCallback = object : LocationCallback() {
        override fun onLocationResult(p0: LocationResult) {
            super.onLocationResult(p0)

            lastLocation = p0.lastLocation
            placeMarkerOnMap(LatLng(lastLocation.latitude, lastLocation.longitude))
        }
    }

    createLocationRequest()

    val fab = findViewById<FloatingActionButton>(R.id.fab)
    fab.setOnClickListener {
        loadPlacePicker()
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        if (resultCode == Activity.RESULT_OK) {
            locationUpdateState = true
            startLocationUpdates()
        }
    }
    if (requestCode == PLACE_PICKER_REQUEST) {
        if (resultCode == RESULT_OK) {
            val place = PlacePicker.getPlace(this, data)
            var addressText = place.name.toString()
            addressText += "\n" + place.address.toString()

            placeMarkerOnMap(place.latLng)
        }
    }
}

override fun onPause() {
    super.onPause()
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

public override fun onResume() {
    super.onResume()
    if (!locationUpdateState) {
        startLocationUpdates()
    }
}

override fun onMapReady(googleMap: GoogleMap) {
    map = googleMap

    map.uiSettings.isZoomControlsEnabled = true
    map.setOnMarkerClickListener(this)

    setUpMap()
}

override fun onMarkerClick(p0: Marker?) = true

private fun setUpMap() {
    if (ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
        return
    }

    map.isMyLocationEnabled = true
    map.mapType = GoogleMap.MAP_TYPE_NORMAL

    fusedLocationClient.lastLocation.addOnSuccessListener(this) { location ->
        // Got last known location. In some rare situations this can be null.
        if (location != null) {
            lastLocation = location
            val currentLatLng = LatLng(location.latitude, location.longitude)
            placeMarkerOnMap(currentLatLng)
            map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))
        }
    }
}

private fun placeMarkerOnMap(location: LatLng) {
    val markerOptions = MarkerOptions().position(location)

    val titleStr = getAddress(location)  // add these two lines
    markerOptions.title(titleStr)

    map.addMarker(markerOptions)

}


private fun startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                LOCATION_PERMISSION_REQUEST_CODE)
        return
    }
    fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null /* Looper */)

}

private fun createLocationRequest() {
    locationRequest = LocationRequest()
    locationRequest.interval = 10000
    locationRequest.fastestInterval = 5000
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

    val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
    val client = LocationServices.getSettingsClient(this)
    val task = client.checkLocationSettings(builder.build())

    task.addOnSuccessListener {
        locationUpdateState = true
        startLocationUpdates()
    }
    task.addOnFailureListener { e ->
        if (e is ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                e.startResolutionForResult(this@MapsActivity,
                        REQUEST_CHECK_SETTINGS)
            } catch (sendEx: IntentSender.SendIntentException) {
                // Ignore the error.
            }
        }
    }
}

private fun loadPlacePicker() {
    val builder = PlacePicker.IntentBuilder()

    try {
        startActivityForResult(builder.build(this@MapsActivity), PLACE_PICKER_REQUEST)
    } catch (e: GooglePlayServicesRepairableException) {
        e.printStackTrace()
    } catch (e: GooglePlayServicesNotAvailableException) {
        e.printStackTrace()
    }
}
}
4

2 回答 2

2

@LordRaydenMK 的回答是正确的。我花了一周的时间试图解决这个问题,最终发现它得到了它。您引用的那个raywenderlich 教程很好,除了他们错误地编码了placeMarkerOnMap()函数。

首先,为上面的位置标记设置一个变量onCreate

private var userLocationMarker: Marker? = null

然后placeMarkerOnMap()用这段代码替换你的函数,它应该可以正常工作:

private fun placeMarkerOnMap(location: Location) {
    val latLng = LatLng(location.latitude, location.longitude)
    if (userLocationMarker == null) {
        //Create a new marker
        val markerOptions = MarkerOptions()
        markerOptions.position(latLng)
        markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_user_location))
        markerOptions.rotation(location.bearing)
        markerOptions.anchor(0.5.toFloat(), 0.5.toFloat())
        userLocationMarker = map.addMarker(markerOptions)
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 20f))
    } else {
        //use the previously created marker
        userLocationMarker!!.position = latLng
        userLocationMarker!!.rotation = location.bearing
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 20f))
    }
}

如果您想摆脱蓝点,请确保设置isMyLocationEnabledfalse.

于 2020-11-13T15:59:55.660 回答
2

GoogleMapaddMarker()方法返回一个Marker

setPosition您需要保留对返回标记的引用,然后使用该方法更新它的位置。

于 2018-02-24T12:26:50.580 回答