在 kotlin 中的 requestLocationUpdates 之后移动标记而不是添加它
Posted
技术标签:
【中文标题】在 kotlin 中的 requestLocationUpdates 之后移动标记而不是添加它【英文标题】:Move marker instead of adding it after requestLocationUpdates in kotlin 【发布时间】:2018-08-04 07:06:51 【问题描述】:在本教程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()
【问题讨论】:
【参考方案1】:GoogleMap 的addMarker()
方法返回一个Marker。
您需要保留对返回标记的引用,然后使用setPosition
方法更新它的位置。
【讨论】:
【参考方案2】:@LordRaydenMK's answer 是正确的。我花了一周的时间试图解决这个问题,最终发现它得到了它。您引用的 raywenderlich tutorial 很好,只是他们错误地编码了 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))
如果您想摆脱蓝点,请确保将isMyLocationEnabled
设置为false
。
【讨论】:
以上是关于在 kotlin 中的 requestLocationUpdates 之后移动标记而不是添加它的主要内容,如果未能解决你的问题,请参考以下文章