每当服务器上的驾驶员位置 (lat lng) 发生变化时,将标记动画化到新位置,例如超级汽车动画

Ara*_*ind 5 animation android

private void GetDriverloc(HashMap<String, String> map) {
    Call<DriverLocationResToCus> call = apiInterface.GetDriverLoc(map);
    System.out.println("enter the currency alert api" + call.request().url());
    call.enqueue(new Callback<DriverLocationResToCus>() {
        @Override
        public void onResponse(Call<DriverLocationResToCus> call, Response<DriverLocationResToCus> response) {


            if (response.isSuccessful()) {

                assert response.body() != null;
                DriverStartLat = response.body().getDriverCurrentLatStart();
                DriverStartLng = response.body().getDriverCurrentLngStart();
                DriverEndLat = response.body().getDriverCurrentLatEnd();
                DriverEndLng = response.body().getDriverCurrentLngEnd();
Run Code Online (Sandbox Code Playgroud)

/这里我从服务器获取驱动程序的位置。我需要将驱动程序 lat lnt 传递给循环并相应地为标记设置动画。我试图将它直接传递给 startpostion 和 endpostion。但标记继续闪烁。

                Utilities.printV("DriverStartLat", DriverStartLat);

                ValueAnimator polylineAnimator = ValueAnimator.ofInt(0, 100);
                polylineAnimator.setDuration(2000);
                polylineAnimator.setInterpolator(new LinearInterpolator());
                polylineAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        List<LatLng> points = greyPolyLine.getPoints();
                        int percentValue = (int) valueAnimator.getAnimatedValue();
                        int size = points.size();
                        int newPoints = (int) (size * (percentValue / 100.0f));
                        List<LatLng> p = points.subList(0, newPoints);
                        blackPolyline.setPoints(p);
                    }
                });
                polylineAnimator.start();



                    mHandler = new Handler();
                    index = -1;
                    next = 1;
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {

                        if (index < points.size() - 1) {
                            index++;
                            next = index + 1;
                        }
                        if (index < points.size() - 1) {
                            startPosition = points.get(index);
                            endPosition = points.get(next);
                        }
Run Code Online (Sandbox Code Playgroud)

//当我将驱动程序的 lat lng 直接传递到 startposition 和 endposition 时,标记移动到新位置,但如果它没有从服务器获取新的 lat lat 并且持续闪烁,它就会返回。

                            ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
                            valueAnimator.setDuration(3000);
                            valueAnimator.setInterpolator(new LinearInterpolator());
                            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                                @Override
                                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                                    v = valueAnimator.getAnimatedFraction();
                                    lng = v * endPosition.longitude + (1 - v)
                                            * startPosition.longitude;
                                    lat = v * endPosition.latitude + (1 - v)
                                            * startPosition.latitude;

                                    LatLng newPos = new LatLng(lat, lng);
                                    marker.setPosition(newPos);
                                    marker.setAnchor(0.5f, 0.5f);
                                    marker.setRotation(getBearing(startPosition, newPos));
                        mMap.moveCamera(CameraUpdateFactory
                                .newCameraPosition
                                        (new CameraPosition.Builder()
                                                .target(newPos)
                                                .zoom(15.5f)
                                                .build()));
                                }
                            });
                            valueAnimator.start();
                            mHandler.postDelayed(this, 3000);
                        }
                    }, 3000);

                Utilities.printV("DriverLocationResToCus", "DriverLocationResToCus SUCCESS");


            } else {

                Utilities.printV("DriverLocationResToCus", "DriverLocationResToCus FAILURE");
                
            }
        }

        @Override
        public void onFailure(Call<DriverLocationResToCus> call, Throwable t) {

        }
    });

}
Run Code Online (Sandbox Code Playgroud)

//谁能帮我解决这个问题

Ara*_*ind 2

从以下链接下载 MarkerAnimation 和 LatLngInterpolator 文件

https://drive.google.com/file/d/1i-pDZYOtf-Vl8m6wnYulGnv3rb9aVMih/view https://drive.google.com/file/d/1AypW3b6YIX6UtYFFuh1-lx7Id1lt0QqP/view

或使用下面发布的代码

标记动画代码:

public class MarkerAnimation {
public static void animateMarkerToGB(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 = 3000;

    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)
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(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(3000);
    animator.start();
}
Run Code Online (Sandbox Code Playgroud)

}

LatLngInterpolator 代码:

public interface LatLngInterpolator {
public LatLng interpolate(float fraction, LatLng a, LatLng b);

public class Linear implements LatLngInterpolator {
    @Override
    public LatLng interpolate(float fraction, LatLng a, LatLng b) {
        double lat = (b.latitude - a.latitude) * fraction + a.latitude;
        double lng = (b.longitude - a.longitude) * fraction + a.longitude;
        return new LatLng(lat, lng);
    }
}

public class LinearFixed implements LatLngInterpolator {
    @Override
    public LatLng interpolate(float fraction, LatLng a, LatLng b) {
        double lat = (b.latitude - a.latitude) * fraction + a.latitude;
        double lngDelta = b.longitude - a.longitude;

        // Take the shortest path across the 180th meridian.
        if (Math.abs(lngDelta) > 180) {
            lngDelta -= Math.signum(lngDelta) * 360;
        }
        double lng = lngDelta * fraction + a.longitude;
        return new LatLng(lat, lng);
    }
}

public class Spherical implements LatLngInterpolator {

    /* From github.com/googlemaps/android-maps-utils */
    @Override
    public LatLng interpolate(float fraction, LatLng from, LatLng to) {
        // http://en.wikipedia.org/wiki/Slerp
        double fromLat = toRadians(from.latitude);
        double fromLng = toRadians(from.longitude);
        double toLat = toRadians(to.latitude);
        double toLng = toRadians(to.longitude);
        double cosFromLat = cos(fromLat);
        double cosToLat = cos(toLat);

        // Computes Spherical interpolation coefficients.
        double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng);
        double sinAngle = sin(angle);
        if (sinAngle < 1E-6) {
            return from;
        }
        double a = sin((1 - fraction) * angle) / sinAngle;
        double b = sin(fraction * angle) / sinAngle;

        // Converts from polar to vector and interpolate.
        double x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng);
        double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng);
        double z = a * sin(fromLat) + b * sin(toLat);

        // Converts interpolated vector back to polar.
        double lat = atan2(z, sqrt(x * x + y * y));
        double lng = atan2(y, x);
        return new LatLng(toDegrees(lat), toDegrees(lng));
    }

    private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng) {
        // Haversine's formula
        double dLat = fromLat - toLat;
        double dLng = fromLng - toLng;
        return 2 * asin(sqrt(pow(sin(dLat / 2), 2) +
                cos(fromLat) * cos(toLat) * pow(sin(dLng / 2), 2)));
    }
}
Run Code Online (Sandbox Code Playgroud)

}

这是在地图上旋转图标(标记)的代码位

private float getBearing(LatLng begin, LatLng end) {
double lat = Math.abs(begin.latitude - end.latitude);
double lng = Math.abs(begin.longitude - end.longitude);

if (begin.latitude < end.latitude && begin.longitude < end.longitude)
    return (float) (Math.toDegrees(Math.atan(lng / lat)));
else if (begin.latitude >= end.latitude && begin.longitude < end.longitude)
    return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude)
    return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180);
else if (begin.latitude < end.latitude && begin.longitude >= end.longitude)
    return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
return -1;
Run Code Online (Sandbox Code Playgroud)

}

这是从 api 获取 Lat 和 Lng 后需要添加的代码。

if(marker == null) { 
                    marker = mMap.addMarker(new MarkerOptions().position(endPosition)
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE)));
                    MarkerAnimation.animateMarkerToGB(marker, endPosition, new LatLngInterpolator.Spherical());
                    marker.setRotation(getBearing(endPosition, startPosition));

                } else {
                    MarkerAnimation.animateMarkerToICS(marker, endPosition, new LatLngInterpolator.Spherical());
                    marker.setRotation(getBearing(endPosition, startPosition));

                }
Run Code Online (Sandbox Code Playgroud)

快乐编码:)

  • 不要只写代码答案。请继续添加解释。 (2认同)