【问题标题】:Shaky Google Maps Marker Animation摇晃的谷歌地图标记动画
【发布时间】: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


    【解决方案1】:

    您现在正在进行异步调用,并且由于您在 maker 上有多个动画,您正面临着紧张不安。

    改用同步方法,即[valueAnimator][1] - 您已在代码中将其注释掉。在文档中观看this video,它解释了为什么以及何时使用它。

    希望对您有所帮助!

    【讨论】:

    • 那么value animator是Synchronized方法?如果我遍历一个坐标列表并为每个坐标调用该方法,它会按顺序运行它们吗?
    • 是的,没错。注意这里:AnimatorUpdateListener()。从视频“onAnimationUpdate override,它在准备下一帧时被调用。”我建议您观看视频,因为他们讨论了三种不同的动画处理方法。
    • 抱歉,为了清楚起见,它会为getPosition 检索到的坐标按顺序运行动画帧。另外,“运行它们”是指按顺序运行每个标记动画吗?如果是这样,我对此表示怀疑,但我会尽快回复您。
    • 是的,例如,如果我传递一个 LatLng 坐标列表,它将从 1 到 2、2 到 3、3 到 4 等进行动画处理。我只是不希望它像它正在尝试同时使用 6 个不同的 LatLng 位置为标记设置动画。
    • 所以它会从 1 移动到 2、2 到 3 等等,仅适用于相应的制造商。而且我认为您想要的是一次运行一个标记,希望我是对的。如果您希望动画一次运行一个标记。为交替位置或其他东西设置不同的延迟。如果您希望动画仅针对地图上的一个(假定)活动标记触发,有一种方法,但我不熟悉。如果我能找到它,我可以告诉你。
    【解决方案2】:

    我的方法是使用处理程序安排一个 Runnable,以便它可以有一些回调来调用以通知动画完成。一旦你从最后一个动画处理程序延迟的可运行中弹出下一个 latlng 对象并运行动画,就立即维护一个用于排队标记位置的链表。

    animator.start() 注册后的 ICS 和 HC 的每个动画方法中,使用 handler.postDelayed() 延迟可运行,其中延迟是动画的确切持续时间

    【讨论】:

      猜你喜欢
      • 2012-12-07
      • 2014-02-20
      • 1970-01-01
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      相关资源
      最近更新 更多