Пожалуйста, посмотрите полное отслеживание маркера, анимируйте и двигайтесь, как убер, с помощью приведенного ниже кода Kotlin:
Первоначально добавьте слушателя Firebase
mFirebaseRef?.child(mDriverId)!!.addChildEventListener(listener);
Определите своего слушателя пожарной базы
var listener = object : ChildEventListener {
override fun onCancelled(p0: DatabaseError) {
Log.e("onCancelled", " " + p0.message)
}
override fun onChildMoved(p0: DataSnapshot, p1: String?) {
Log.e("onChildMoved", " " + p0.key)
}
override fun onChildChanged(dataSnapshot: DataSnapshot, p1: String?) {
Log.e("onChildChanged", " " + dataSnapshot.key)
//Write your database reference login for getting Lat Lng
if (dataSnapshot.key.equals("l")) {
val latLatLng = dataSnapshot.value as ArrayList<Any>?
if (latLatLng!!.size == 2) {
displayLocation(latLatLng)
}
}
}
override fun onChildAdded(p0: DataSnapshot, p1: String?) {
Log.e("onChildAdded", " " + p0.key)
}
override fun onChildRemoved(p0: DataSnapshot) {
Log.e("onChildRemoved", " " + p0.key)
}
}
Добавление и обновление маркера с начальным увеличением для первого раза
private fun displayLocation(latLatLng: ArrayList<Any>) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION)
} else {
mLastLocation = Location(LocationManager.GPS_PROVIDER)
mLastLocation!!.latitude = latLatLng[0] as Double;
mLastLocation!!.longitude = latLatLng[1] as Double;
val latitude = latLatLng[0]!!
val longitude = latLatLng[1]!!
addMarker(mMap, latitude as Double, longitude as Double)
if (isFirstTime) {
isFirstTime = false
try {
var pickUPLatLng: LatLng = LatLng(pick_lat.toDouble(), pick_long.toDouble())
var deliveryLatLng: LatLng = LatLng(drop_lat.toDouble(), drop_long.toDouble())
var latLngBounds: LatLngBounds = LatLngBounds.Builder()
.include(pickUPLatLng)
.include(deliveryLatLng)
.include(LatLng(latitude as Double, longitude as Double))
.build()
lstLatLngRoute.clear()
try {
mLastLocation = Location(LocationManager.GPS_PROVIDER)
mLastLocation!!.longitude = longitude as Double
mLastLocation!!.latitude = latitude as Double
lstLatLngRoute.add(LatLng(mLastLocation!!.latitude, mLastLocation!!.longitude))
} catch (e: Exception) {
e.printStackTrace()
}
lstLatLngRoute.add(pickUPLatLng)
lstLatLngRoute.add(deliveryLatLng)
zoomRoute(mMap!!, lstLatLngRoute)
//mMap!!.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 250))
//mMap!!.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(latitude as Double, longitude as Double), 14f))
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
Теперь добавьте маркер, если он еще не добавлен на Карту Google, или используйте предыдущий раз
private var markerCount: Int = 0
private var marker: Marker? = null;
private var mLastLocation: Location? = null
fun addMarker(googleMap: GoogleMap?, lat: Double, lon: Double) {
if (markerCount == 1) {
try {
try {
animateMarker(marker!!, LatLng(mLastLocation!!.latitude, mLastLocation!!.longitude))
} catch (e: Exception) {
}
} catch (e: Exception) {
e.printStackTrace()
}
} else if (markerCount == 0) {
var pickUpBmp: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.carbike)
mMap = googleMap
val latlong = LatLng(lat, lon)
marker = mMap!!.addMarker(MarkerOptions().position(LatLng(lat, lon))
.icon(BitmapDescriptorFactory.fromBitmap(pickUpBmp))
.anchor(0.5f, 0.5f)
.flat(false))
mMap!!.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, MAP_ZOOM_LEVEL))
markerCount = 1
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
}
}
И, наконец, просто анимируйте маркер следующим способом:
fun animateMarker( marker: Marker,toPosition: LatLng) {
val handler = Handler()
val start = SystemClock.uptimeMillis()
val proj = mMap!!.getProjection()
val startPoint = proj.toScreenLocation(marker.getPosition())
val startLatLng = proj.fromScreenLocation(startPoint)
val duration: Long = 3000
val interpolator = LinearInterpolator()
handler.post(object : Runnable {
override fun run() {
val elapsed = SystemClock.uptimeMillis() - start
val t = interpolator.getInterpolation(elapsed.toFloat() / duration)
val lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude
val lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude
marker.position = LatLng(lat, lng)
marker.rotation = (getBearingBetweenTwoPoints1(startLatLng, toPosition).toString().toFloat())
runOnUiThread(Runnable {
mMap!!.moveCamera(CameraUpdateFactory
.newCameraPosition(CameraPosition.Builder()
.target(toPosition)
.zoom(MAP_ZOOM_LEVEL)
.build()))
})
if (t < 1.0) {
handler.postDelayed(this, 16)
}
}
})
}
Используйте приведенные ниже методы для расчета маркера подшипника или головки
private fun getBearingBetweenTwoPoints1(latLng1: LatLng, latLng2: LatLng): Double {
val lat1 = degreesToRadians(latLng1.latitude)
val long1 = degreesToRadians(latLng1.longitude)
val lat2 = degreesToRadians(latLng2.latitude)
val long2 = degreesToRadians(latLng2.longitude)
val dLon = long2 - long1
val y = Math.sin(dLon) * Math.cos(lat2)
val x = Math.cos(lat1) * Math.sin(lat2) - (Math.sin(lat1)
* Math.cos(lat2) * Math.cos(dLon))
val radiansBearing = Math.atan2(y, x)
return radiansToDegrees(radiansBearing)
}
private fun degreesToRadians(degrees: Double): Double {
return degrees * Math.PI / 180.0
}
private fun radiansToDegrees(radians: Double): Double {
return radians * 180.0 / Math.PI
}
Надеюсь, это поможет вам, если вы знакомы с Kotlin:)
@ mohamedgaber Не нужно путать, просто обновите ваш слушатель следующим образом, и он будет работать для количества детей (маркеров), а не для одного маркера (убедитесь, что ваши маркеры разные). Просто конвертируйте этот слушатель в Koltin и используйте другой код, который я дал, обещаю, что он будет работать очень гладко, как Uber.
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Double lang = ds.child("lang").getValue(Double.class);
Double lat = ds.child("lat").getValue(Double.class);
save = new model(lat, lang);
ll = new LatLng(save.getLat(), save.getLang());
displayLocation(ll)
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});