【问题标题】:Marker Animation on Google Maps Android not working谷歌地图Android上的标记动画不起作用
【发布时间】:2016-08-25 07:56:06
【问题描述】:

我正在尝试为我的标记设置动画,而不是让它在 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,在animateMarker 方法中的duration 中使用。

【问题讨论】:

  • 标记的位置正确吗?只是动画不行,速度太快了,好像是跳跃,你希望它顺利进行对吧?
  • 是的,你是正确的,移动到正确的位置,只是不顺利。

标签: android google-maps-android-api-2 google-maps-api-2


【解决方案1】:

您可以像这样从头到尾平滑标记的动画:

LatLng[] line = bezier(startPosition, endPosition, 0, 0, true);
Marker marker = mMap.addMarker(new MarkerOptions().position(startPosition));
animateMarker(marker, 0, line);

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

请在我的 GitHub 上查看完整示例

【讨论】:

  • 我会尝试并报告。谢谢
  • 是的,这非常有效。我不得不将你所有的文件从你的 github 链接中使用到我的项目中。谢谢。
  • 将赏金分配给您。谢谢。
  • 有一个问题。动画在更新持续时间的大约 80% 内有效,在剩余的 20% 内跳跃。有什么理由吗?我可以把它微调到 5% 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
相关资源
最近更新 更多