摇摇欲坠的谷歌地图标记动画 [英] Shaky Google Maps Marker Animation

查看:267
本文介绍了摇摇欲坠的谷歌地图标记动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图动画在谷歌地图标记。那我遇到的问题是,如何标记都表现的时候,是时候为他们制作动画。标记沿一给定的点集移动,但它们开始晃动而剧烈,或它们将沿着一组路径移动并且似乎是橡皮带,或跳回到原来的开始位置。

有没有人处理这个问题之前?如果是这样,你怎么解决?我目前使用这是谷歌通过提供开发者处理动画code的有些修改后的版本。

更新:我认为问题是由试图在一个给定的标记同时运行多个动画所致。这是导致标记来回跳动所有新/老位置之间。

下面是code处理该动画调用,方法传递从而重新present标记应遵循的路径LatLngs的列表。

 公共无效animateMarker(字符串键,列表与LT;经纬度> latlngList){
    AnimateCarObj animateCarObj = animateCarObjMap.get(键);
    标记标记= markersHashMap.get(键);    如果(标记!= NULL){        的LatLng preV =新的经纬度(0,0);
        为(经纬度经纬度:latlngList){
            如果(!(latlng.equals(preV))){
                尝试{
                    LatLngInterpolator latlonInter =新LinearFixed();
                    latlonInter.interpolate(1,animateCarObj.getGps1(),经纬度);                    MarkerAnimation.animateMarker(latlngList.size(),标记,经纬度,latlonInter);
                    preV =经纬度;                }赶上(例外五){
                    Log.e(TAG,EXCEPTION+ e.getMessage());
                    e.printStackTrace();
                }
            }
        }
    }
}

MarkerAnimation类,我修改这个类采取所谓的台阶的整数值,这是为了让动画将在一个穿过所有的点不管返回多少分均匀的速度通过一个请求。在本实施例,它采用的默认值为3,由10000毫秒相乘,并且比由步数除以它

 <$ C C>公共类MarkerAnimation {    公共静态无效animateMarker(INT步骤,最终标记标记,最后的经纬度finalPosition,
                                                                        最终LatLngInterpolator latLngInterpolator){
        如果(标记== NULL || finalPosition == NULL || latLngInterpolator == NULL){返回; }
        如果(Build.VERSION.SDK_INT&LT; Build.VERSION_ codeS.HONEYCOMB_MR1){
            animateMarkerToGB(步骤,标记,finalPosition,latLngInterpolator);
        }其他{
            animateMarkerToICS(步骤,标记,finalPosition,latLngInterpolator);
        }
    }    公共静态无效animateMarkerToGB(INT步骤,最终标记标记,最后的经纬度finalPosition,
                                                                                最终LatLngInterpolator latLngInterpolator){
        最后的经纬度=指定startPosition marker.getPosition();
        最后的处理程序处理程序=新的处理程序();
        最终长启动= SystemClock.uptimeMillis();
        最终插补插补器=新AccelerateDecelerateInterpolator();
        最终浮动durationInMs =(CarListStore.DEFAULT_ALIVE_COUNT * 10000)/步;        handler.post(新的Runnable(){
            经过很长;
            浮吨;
            浮伏;            @覆盖
            公共无效的run(){
                //使用插值计算进度
                经过= SystemClock.uptimeMillis() - 启动;
                T =已过/ durationInMs;
                V = interpolator.getInterpolation(T);                marker.setPosition(latLngInterpolator.interpolate(ⅴ,指定startPosition,finalPosition));                //重复直到进度完成。
                如果(T&LT; 1){
                    再后来16毫秒后//。
                    handler.postDelayed(这一点,16);
                }
            }
        });
    }    / * @TargetApi(Build.VERSION_ codeS.HONEYCOMB)
        公共静态无效animateMarkerToHC(最终标记标记,最后的经纬度finalPosition,
                                                                                    最终LatLngInterpolator latLngInterpolator){
            最后的经纬度=指定startPosition marker.getPosition();            ValueAnimator valueAnimator =新ValueAnimator();
            valueAnimator.addUpdateListener(新ValueAnimator.AnimatorUpdateListener(){
                @覆盖
                公共无效onAnimationUpdate(ValueAnimator动画){
                    浮V = animation.getAnimatedFraction();
                    经纬度在newPosition = latLngInterpolator.interpolate(V,指定startPosition,finalPosition);
                    marker.setPosition(在newPosition);
                }
            });
            valueAnimator.setFloatValues​​(0,1); //忽略。
            valueAnimator.setDuration(3000);
            valueAnimator.start();
        } * /    @TargetApi(Build.VERSION_ codeS.ICE_CREAM_SANDWICH)
    公共静态无效animateMarkerToICS(INT步骤,标记标记,经纬度finalPosition,最终LatLngInterpolator latLngInterpolator){
        TypeEvaluator&LT;&经纬度GT; typeEvaluator =新TypeEvaluator&LT;&经纬度GT;(){
            @覆盖
            公共经纬度计算(浮点分数,经纬度在startValue,经纬度endValue值){
                返回latLngInterpolator.interpolate(分数,在startValue,endValue值);
            }
        };
        地产&LT;标记,经纬度&GT;财产= Property.of(Marker.class,LatLng.class,位置);
        ObjectAnimator动画= ObjectAnimator.ofObject(标记,财产,typeEvaluator,finalPosition);
        animator.setDuration((CarListStore.DEFAULT_ALIVE_COUNT * 10000)/步);
        animator.start();
    }
}


解决方案

我的方法是安排一个Runnable使用处理器使得它能够有一定的回调来电话通知动画完成。只要你保持排队标记位置的链接列表的onComplete 从去年的动画处理程序回调延迟可运行流行的下一个经纬度对象从队列和运行动画。

在为ICS和放大器每个动画的方法; HC后 animator.start()注册使用延迟可运行 handler.postDelayed(),其中延迟的确切时间动画

I am attempting to animate markers on a Google Map. The issue that I am running into is how the markers are behaving when it is time for them to animate. The markers are moving along a given set of points, but they start shaking rather violently, or they will move along a set path and appear to be rubberbanding, or jumping back to the original start position.

Has anyone dealt with this issue before? and if so, how did you fix it? I am currently using a somewhat modified version of code that was provided by Google devs to handle animation.

UPDATE: I believe the issue is caused by trying to run many animations simultaneously on a given Marker. This is causing the marker to bounce back and forth between all the new/old positions.

Here is the code that handles the Animation calls, the method is passed a list of LatLngs which represent the path the marker should follow.

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, I modified this class to take an Integer value called "steps", this is so that the animation will pass through all the points at an even pace regardless of how many points are returned through a request. In this example, it uses a default value of 3, multiplies it by 10000 ms, and than divides it by the step count.

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();
    }
}

解决方案

My method is to schedule a Runnable using handler such that it can have some callback to call to notify animation is complete. Maintain a linked list for queueing marker position as soon as you get OnComplete callback from last animation handler delayed runnable pop the next latlng object from the queue and run the animation.

In each animation method for ICS & HC after animator.start() register delayed runnable using handler.postDelayed() where the delay is exact duration of the animation

这篇关于摇摇欲坠的谷歌地图标记动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆