【发布时间】:2015-08-08 17:26:59
【问题描述】:
我正在尝试为 Google 地图上的标记设置动画。我遇到的问题是标记在制作动画时的行为方式。标记沿着给定的一组点移动,但它们开始剧烈摇晃,或者它们将沿着设定的路径移动并且看起来像橡皮筋一样,或者跳回原来的起始位置。
以前有人处理过这个问题吗?如果是这样,您是如何解决的?我目前正在使用 Google 开发人员提供的稍微修改过的代码版本来处理动画。
更新:我认为问题是由于尝试在给定标记上同时运行多个动画造成的。这导致标记在所有新/旧位置之间来回反弹。
这里是处理动画调用的代码,该方法被传递一个 LatLngs 列表,代表标记应该遵循的路径。
public void animateMarker(String key, List<LatLng> latlngList) {
AnimateCarObj animateCarObj = animateCarObjMap.get(key);
Marker marker = markersHashMap.get(key);
if (marker != null) {
LatLng prev = new LatLng(0, 0);
for (LatLng latlng : latlngList) {
if (!(latlng.equals(prev))) {
try {
LatLngInterpolator latlonInter = new LinearFixed();
latlonInter.interpolate(1, animateCarObj.getGps1(), latlng);
MarkerAnimation.animateMarker(latlngList.size(), marker, latlng, latlonInter);
prev = latlng;
} catch (Exception e) {
Log.e(TAG, "EXCEPTION: " + e.getMessage());
e.printStackTrace();
}
}
}
}
}
MarkerAnimation 类,我将这个类修改为一个整数值,称为“steps”,这样无论返回多少点,动画都会以均匀的速度通过所有点通过请求。在此示例中,它使用默认值 3,将其乘以 10000 毫秒,然后再除以步数。
public class MarkerAnimation {
public static void animateMarker(int steps, final Marker marker, final LatLng finalPosition,
final LatLngInterpolator latLngInterpolator) {
if (marker == null || finalPosition == null || latLngInterpolator == null) { return; }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
animateMarkerToGB(steps, marker, finalPosition, latLngInterpolator);
} else {
animateMarkerToICS(steps, marker, finalPosition, latLngInterpolator);
}
}
public static void animateMarkerToGB(int steps, final Marker marker, final LatLng finalPosition,
final LatLngInterpolator latLngInterpolator) {
final LatLng startPosition = marker.getPosition();
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final Interpolator interpolator = new AccelerateDecelerateInterpolator();
final float durationInMs = (CarListStore.DEFAULT_ALIVE_COUNT * 10000) / steps;
handler.post(new Runnable() {
long elapsed;
float t;
float v;
@Override
public void run() {
// Calculate progress using interpolator
elapsed = SystemClock.uptimeMillis() - start;
t = elapsed / durationInMs;
v = interpolator.getInterpolation(t);
marker.setPosition(latLngInterpolator.interpolate(v, startPosition, finalPosition));
// Repeat till progress is complete.
if (t < 1) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
}
/* @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static void animateMarkerToHC(final Marker marker, final LatLng finalPosition,
final LatLngInterpolator latLngInterpolator) {
final LatLng startPosition = marker.getPosition();
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, finalPosition);
marker.setPosition(newPosition);
}
});
valueAnimator.setFloatValues(0, 1); // Ignored.
valueAnimator.setDuration(3000);
valueAnimator.start();
}*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static void animateMarkerToICS(int steps, Marker marker, LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {
TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
return latLngInterpolator.interpolate(fraction, startValue, endValue);
}
};
Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");
ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
animator.setDuration((CarListStore.DEFAULT_ALIVE_COUNT * 10000) / steps);
animator.start();
}
}
【问题讨论】:
标签: android google-maps animation google-maps-markers