我想在Android上像uber一样在Map上设置动画并旋转我的车。我在Firebase实时数据库上保存位置。并从Firebase实时获取位置。
我的代码在下面-------->
private void subscribeToUpdates(final String driver_id) {
ref = FirebaseDatabase.getInstance().getReference(getString(R.string.firebase_path));
childListener= ref.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
setMarker(dataSnapshot, driver_id);
Log.v("datanap", String.valueOf(dataSnapshot));
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
setMarker(dataSnapshot, driver_id);
Log.v("datanap", String.valueOf(dataSnapshot));
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onCancelled(DatabaseError error) {
Log.d("TAG", "Failed to read value.", error.toException());
}
});
}
,我正在创建我的地图标记并在此代码中进行更新。而且我尝试了一些动画和旋转方法,但无法正常工作。
private void setMarker(DataSnapshot dataSnapshot, String driver_id) {
// When a location update is received, put or update
// its value in mMarkers, which contains all the markers
// for locations received, so that we can build the
// boundaries required to show them all on the map at once
String key = dataSnapshot.child(driver_id).getKey();
Log.v("datasnap", key);
HashMap<String, Object> value = (HashMap<String, Object>) dataSnapshot.getValue();
double lat = Double.parseDouble(value.get("latitude").toString());
double lng = Double.parseDouble(value.get("longitude").toString());
LatLng location = new LatLng(lat, lng);
if (!mMarkers.containsKey(key)) {
startPosition = new LatLng(lat, lng);
Log.v("startPos", String.valueOf(startPosition));
// marker= mMap.addMarker(new MarkerOptions().title(key).position(location).icon(BitmapDescriptorFactory.fromResource(R.mipmap.truck_top)).flat(true));
mMarkers.put(key,mMap.addMarker(new MarkerOptions().title(key).position(location).icon(BitmapDescriptorFactory.fromResource(R.mipmap.truck_top)).flat(true)));
Log.v("trackLog", "Marker created");
} else {
endPosition = new LatLng(lat, lng);
Log.v("endPos", String.valueOf(endPosition));
mMarkers.get(key).setPosition(location);
// startBikeAnimation(startPosition,endPosition,key);
Log.v("trackLog", "Marker updated");
// animatedMarker(startPosition, endPosition, mMarkers.get(key));
}
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : mMarkers.values()) {
builder.include(marker.getPosition());
}
if (!isAnimated) {
isAnimated = true;
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 300));
}
}
我已经尝试过此代码。
private void startBikeAnimation(final LatLng start, final LatLng end, final String key) {
Log.i(TAG, "startBikeAnimation called...");
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(ANIMATION_TIME_PER_ROUTE);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//LogMe.i(TAG, "Car Animation Started...");
v = valueAnimator.getAnimatedFraction();
lngg = v * end.longitude + (1 - v)
* start.longitude;
latt = v * end.latitude + (1 - v)
* start.latitude;
LatLng newPos = new LatLng(latt, lngg);
mMarkers.get(key).setPosition(newPos);
mMarkers.get(key).setAnchor(0.5f, 0.5f);
mMarkers.get(key).setRotation(getBearing(start, end));
// todo : Shihab > i can delay here
mMap.moveCamera(CameraUpdateFactory
.newCameraPosition
(new CameraPosition.Builder()
.target(newPos)
.zoom(15.5f)
.build()));
startPosition = mMarkers.get(key).getPosition();
}
});
valueAnimator.start();
}
public static float getBearing(LatLng begin, LatLng end) {
double lat = Math.abs(begin.latitude - end.latitude);
double lng = Math.abs(begin.longitude - end.longitude);
if (begin.latitude < end.latitude && begin.longitude < end.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)));
else if (begin.latitude >= end.latitude && begin.longitude < end.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180);
else if (begin.latitude < end.latitude && begin.longitude >= end.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
return -1;
}