我正在尝试在Google地图上制作标记。我遇到的问题是标记在动画时的表现。标记沿着给定的一组点移动,但是它们开始相当猛烈地摇动,或者它们将沿着设定路径移动并且看起来是橡皮筋,或者跳回到原始起始位置。
以前有人处理过这个问题吗?如果是这样,你是如何修复它的?我目前正在使用由Google开发人员提供的稍微修改过的代码来处理动画。
更新:我认为问题是由于尝试在给定标记上同时运行多个动画而引起的。这导致标记在所有新/旧位置之间来回反弹。
这是处理动画调用的代码,该方法传递一个LatLng列表,代表标记应遵循的路径。
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 Class ,我修改了这个类以获取一个名为&#34;&#34;的整数值,这样动画将以均匀的速度通过所有点,而不管通过请求返回多少个点。在此示例中,它使用默认值3,将其乘以10000 ms,然后将其除以步数。
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();
}
}
答案 0 :(得分:0)
您正在进行异步调用,因为您在制造商上有多个动画,您将面临紧张情绪。
使用同步方法,即[valueAnimator][1]
- 您已在代码中注释掉它。在文档中观看this video,它解释了为什么以及何时使用它。
希望它有所帮助!
答案 1 :(得分:0)
我的方法是使用处理程序安排Runnable,以便它可以有一些回调来调用通知动画完成。一旦从上一个动画处理程序获得OnComplete
回调,就会保留排队标记位置的链接列表。延迟runnable从队列中弹出下一个latlng对象并运行动画。
在ICS的每种动画方法中animator.start()
注册后的HC使用handler.postDelayed()
延迟runnable,其中延迟是动画的完全持续时间