为了账号安全,请及时绑定邮箱和手机立即绑定

Google Maps v2上的动画标记

/ 猿问

Google Maps v2上的动画标记

摇曳的蔷薇 2019-12-27 09:12:30

使用v2 API在Google Maps上标记标记的最佳方法是什么?

我正在开发一个以地图为中心的游戏,该游戏可以跟踪人的位置并将其显示在地图上以便彼此查看。随着人们的移动,我想为标记从当前到最近的位置设置动画。每个人都有方向,因此我需要适当旋转标记。

使用新的Google Maps API的最佳方法是什么?


查看完整描述

3 回答

?
慕雪9262066

一些Google工程师提供了一个不错的演示视频,其中包含一些优雅的示例代码,这些示例代码说明了如何针对Android的所有不同版本,对起点和终点之间的标记进行动画处理:


相关代码在这里:


https://gist.github.com/broady/6314689


还有一个很好的演示视频,介绍了所有这些操作。


http://youtu.be/WKfZsCKSXVQ


以下是旧的建议答案


在文档中,提到不能更改标记图标:


图标


为标记显示的位图。如果未设置该图标,则显示默认图标。您可以使用defaultMarker(float)指定默认图标的替代颜色。创建标记后,您将无法更改图标。


Google Maps API v2文档


您可能必须跟踪特定的标记,也许使用与此处描述的方法类似的方法:将标记链接到对象,然后找出需要更新的标记。调用.remove()标记,然后根据所需的“方向”创建旋转的图像,使用该图像创建新的标记,然后将新的标记添加到地图。


您无需“清除”地图,只需删除要修改的标记,创建一个新标记,然后将其添加回地图即可。


不幸的是,新的Maps API还不是很灵活。希望Google继续改进它。


查看完整回答
反对 回复 2019-12-27
?
开满天机

用法示例为DiscDev的答案(上图):


LatLng fromLocation = new LatLng(38.5, -100.4); // Whatever origin coordinates

LatLng toLocation = new LatLng(37.7, -107.7); // Whatever destination coordinates

Marker marker = mMap.addMarker(new MarkerOptions().position(firstLocation));

MarkerAnimation.animateMarkerToICS(marker, toLocation, new LatLngInterpolator.Spherical());

对于使用GPS /或接收位置更新的任何位置提供程序的用户:


Marker ourGlobalMarker;

// We've got a location from some provider of ours, now we can call:

private void updateMarkerPosition(Location newLocation) {


    LatLng newLatLng = new LatLng(newLocation.getLatitude(), newLocation.getLongitude());


    if(ourGlobalMarker == null) { // First time adding marker to map

        ourGlobalMarker = mMap.addMarker(new MarkerOptions().position(newLatLng));

    }

    else {

        MarkerAnimation.animateMarkerToICS(ourGlobalMarker, newLatLng, new LatLngInterpolator.Spherical());

    }         

}

重要:


在内,1MarkerAnimation.java如果将动画持续时间设置为X,并且您收到的位置更新速率小于X,则将触发多个动画,并且您可能会看到标记动画有点闪烁(这不是很好的用户体验)。


为避免这种情况,该animationMarkerToICS方法(animationMarkerToICS例如我在这里的示例)应该看起来像这样,


完整的方法实现:


private static Animator animator; // MAKING ANIMATOR GLOBAL INSTEAD OF LOCAL TO THE STATIC FUNCTION


...


// Ice Cream Sandwich compatible

@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");


    // ADD THIS TO STOP ANIMATION IF ALREADY ANIMATING TO AN OBSOLETE LOCATION

    if(animator != null && animator.isRunning()) {

        animator.cancel();

        animator = null;

    }

    animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);

    animator.setDuration((long) ANIMATION_DURATION);

    animator.start();

}

请享用。


查看完整回答
反对 回复 2019-12-27
?
慕的地8271018

 //Your code         

    double bearing = 0.0;

             bearing = getBearing(new LatLng(

                                                currentPosition.latitude

                                                ,currentPosition.longitude),

                                        new LatLng(

                                                nextPosition.latitude,

                                                nextPosition.longitude));  


          bearing -= 90;

                            CameraPosition cameraPosition = new CameraPosition

                                    .Builder()

                                    .target(new LatLng(nextPosition.latitude, nextPosition.longitude))

                                    .bearing((float) bearing)

                                    .zoom(ZOOM_LEVEL).build();



                            mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000, null);


                 animatedMarker(currentPosition,nextPosition,busMarker);




                //Method for finding bearing between two points

                    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;

                    }


   private void animatedMarker(final LatLng startPosition,final LatLng nextPosition,final Marker mMarker)

    {


        final Handler handler = new Handler();

        final long start = SystemClock.uptimeMillis();

        final Interpolator interpolator = new AccelerateDecelerateInterpolator();

        final float durationInMs = 3000;

        final boolean hideMarker = false;


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


                LatLng currentPosition = new LatLng(

                        startPosition.latitude * (1 - t) + nextPosition.latitude * t,

                        startPosition.longitude * (1 - t) + nextPosition.longitude * t);


                mMarker.setPosition(currentPosition);


                // Repeat till progress is complete.

                if (t < 1) {

                    // Post again 16ms later.

                    handler.postDelayed(this, 16);

                } else {

                    if (hideMarker) {

                        mMarker.setVisible(false);

                    } else {

                        mMarker.setVisible(true);

                    }

                }

            }

        });


    }


查看完整回答
反对 回复 2019-12-27

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信