我试图为我的标记设置动画,而不是让它在2点之间跳转。出于某种原因,动画不起作用。
每当我获得新的当前位置时,我都会调用以下代码。
if (currentLatitude != 0 && currentLongitude != 0) {
String actualRideStartTime = "";
if (currentRideTracking.getActualRideStartTime() != 0) {
actualRideStartTime = TIME_FORMAT.format(currentRideTracking
.getActualRideStartTime());
}
vehicleLocation = new LatLng(currentLatitude, currentLongitude);
markerOptions = new MarkerOptions().
.position(vehicleLocation);
animateMarker(map.addMarker(markerOptions), vehicleLocation, false);
// builder.include(vehicleLocation);
}
AnimateMarker方法
public void animateMarker(final Marker marker, final LatLng toPosition,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = God.DRIVER_LOCATION_UPDATE_FREQUENCY;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
Log.d(God.LOG_TAG, ">"+lat+"<"+lng) ;
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
marker.setVisible(false);
} else {
marker.setVisible(true);
marker.showInfoWindow();
}
}
}
});
}
我尝试评论// builder.include(vehicleLocation);
,但顺利的动作不会发生,而是像往常一样向前跳跃。
修改:更新频率是否重要?我正在使用googleapiclient
,所以我不知道更新的频率。最长等待时间已设置为God.DRIVER_LOCATION_UPDATE_FREQUENCY
,duration
方法中的animateMarker
使用了该时间。
答案 0 :(得分:1)
You can smooth animation for marker from start to end smth like this:
LatLng[] line = bezier(startPosition, endPosition, 0, 0, true);
Marker marker = mMap.addMarker(new MarkerOptions().position(startPosition));
animateMarker(marker, 0, line);
and
private static void animateMarker(final Marker marker, final int current, final LatLng[] line) {
if (line == null || line.length == 0 || current >= line.length) {
return;
}
ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, line[current]);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
animateMarker(marker, current + 1, line);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.setDuration(DURATION);
animator.start();
}
private static LatLng[] bezier(LatLng p1, LatLng p2, double arcHeight, double skew, boolean up) {
ArrayList<LatLng> list = new ArrayList<>();
try {
if (p1.longitude > p2.longitude) {
LatLng tmp = p1;
p1 = p2;
p2 = tmp;
}
LatLng c = new LatLng((p1.latitude + p2.latitude) / 2, (p1.longitude + p2.longitude) / 2);
double cLat = c.latitude;
double cLon = c.longitude;
//add skew and arcHeight to move the midPoint
if (Math.abs(p1.longitude - p2.longitude) < 0.0001) {
if (up) {
cLon -= arcHeight;
} else {
cLon += arcHeight;
cLat += skew;
}
} else {
if (up) {
cLat += arcHeight;
} else {
cLat -= arcHeight;
cLon += skew;
}
}
list.add(p1);
//calculating points for bezier
double tDelta = 1.0 / 10;
CartesianCoordinates cart1 = new CartesianCoordinates(p1);
CartesianCoordinates cart2 = new CartesianCoordinates(p2);
CartesianCoordinates cart3 = new CartesianCoordinates(cLat, cLon);
for (double t = 0; t <= 1.0; t += tDelta) {
double oneMinusT = (1.0 - t);
double t2 = Math.pow(t, 2);
double y = oneMinusT * oneMinusT * cart1.y + 2 * t * oneMinusT * cart3.y + t2 * cart2.y;
double x = oneMinusT * oneMinusT * cart1.x + 2 * t * oneMinusT * cart3.x + t2 * cart2.x;
double z = oneMinusT * oneMinusT * cart1.z + 2 * t * oneMinusT * cart3.z + t2 * cart2.z;
LatLng control = CartesianCoordinates.toLatLng(x, y, z);
list.add(control);
}
list.add(p2);
} catch (Exception e) {
Log.e(TAG, "bezier error : ", e);
}
LatLng[] result = new LatLng[list.size()];
result = list.toArray(result);
return result;
}
Please, see full example on my GitHub