android - 如何像 Android 中的 uber 一样在地图上为我的汽车设置动画和旋转?
问题描述
我想像 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;
}
解决方案
推荐阅读
- sql-server-ce - 更改现有 SQL Server CE 数据库的密码异常
- angular - 如何将表单输入动态添加到反应表单角度
- rust - 在闭包中借用可变引用对向量进行排序
- airflow-scheduler - 管理多租户 Airflow 实例中的连接
- amazon-web-services - 向 AWS Fargate ENI 添加或删除安全组以运行 ECS 任务
- r - 有没有办法使用循环和条件在 R 中创建数据框?
- vba - 如何在访问中使用 VBA 将变量从一个 From 传递到另一个表单
- ruby-on-rails - 嵌套控制器中的 Rails 6 Dup
- python - 包含不同 dtype 的 numpy 数组的 Numpy 数组
- amazon-web-services - Snakemake 和 Tibanna:找不到字段“snakemake_main_filename”