如何在Google Maps v2 Android中平滑地移动当前位置标记?

12
我已经在我的位置上放置了一个标记。我希望能够像谷歌地图应用程序一样平稳地移动我的标记。当我开车时,蓝色圆圈移动得非常平滑。我想在我的应用程序中实现相同的效果。我该如何在我的应用程序中实现这一点?
目前,我的位置标记只会在每次位置变化时跳跃到不同的位置并标记那里。
以下是我所做的:
 googleMap.setMyLocationEnabled(true);

因此,onMyLocationChange方法会自动调用:

@Override
public void onMyLocationChange(Location location) 
{
    curlat = location.getLatitude();
    curlong = location.getLongitude();

    if (markermylocation != null)
    {
        markermylocation.remove();
    }

        curlat = location.getLatitude();
        curlong = location.getLongitude();
        myLocation(curlat, curlong, username, imageURL, ZOOMVALUE);
}

在我的位置方法中:

private void myLocation(double lat, double lng, String name, String url, float zoom)
{
    if(firsttime  == 1)
    {
        LatLng ll = new LatLng(lat,lng);
        CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
        googleMap.animateCamera(update);
        firsttime = 0;
    }

    final String uname = name; 
    curlat = lat;
    curlong = lng;
    LatLng position = new LatLng(curlat, curlong);

    markerOptionsmylocaiton = new MarkerOptions().position(position).icon(BitmapDescriptorFactory.fromBitmap(icon)).title(uname).anchor(0.5f, 1f);
    markermylocation = googleMap.addMarker(markerOptionsmylocaiton);

    LatLng latlang = new LatLng(curlat, curlong);
    animateMarker(markermylocation, latlang, false);
}

每次调用我的位置时,标记都会被移除并调用我的位置方法,然后在新的位置创建标记。而我想要像谷歌地图一样获得标记的平滑过渡。如何实现?
更新:
在多次尝试后,我最终写出了以下代码,但我的标记没有显示:
我正在使用下面的方法,并在每次 myLocation 方法中调用它。
public void animateMarker(final Marker marker, final LatLng toPosition,
        final boolean hideMarker) 
{
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    Projection proj = googleMap.getProjection();
    Point startPoint = proj.toScreenLocation(marker.getPosition());
    final LatLng startLatLng = proj.fromScreenLocation(startPoint);
    final long duration = 500;

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

            if (t < 1.0) 
            {
                // Post again 16ms later.
                handler.postDelayed(this, 16);
            } 
            else 
            {
                if (hideMarker) 
                {
                    marker.setVisible(false);
                } 
                else 
                {
                    marker.setVisible(true);
                }
            }
        }
    });
}

谢谢!

2个回答

3

嗨,我在我的一个项目中也有同样的情况,它像魔法一样运作。

在此行后添加以下代码片段:

marker.setPosition(new LatLng(lat, lng));

 //this code
 if (googleMap != null)
         googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 15.0f));

希望这能帮到您。 谢谢。


1

您需要使用插值器,线性或加速插值器,将位置的新latlng和标记的当前latlng之间进行插值。以下是一个带有弹跳插值器的示例。

final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final long duration = 2500;

        final Interpolator interpolator = new BounceInterpolator();
        marker.setVisible(true);

        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = Math.max(
                        1 - interpolator.getInterpolation((float) elapsed
                                / duration), 0);

                marker.setAnchor(0.5f, 1.0f + 6 * t);
                marker.setPosition(latlng)

                if (t > 0.0) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });

谢谢您的快速回复。让我处理一下,然后再回来。我很惊讶移动标记这么难。 :( - TheDevMan
可运行对象是制作简单动画的好帮手。是的,它有点棘手但并不难。您可以轻松更改标记的经纬度。marker.setPosition(latlng),但这也会有些笨拙。 - danny117
终于有机会来处理这个问题了。我使用了你的逻辑和其他参考,编写了上述代码。问题是当使用它时,我根本看不到我的标记。它出现了然后又消失了。请看一下我的代码。告诉我可能出了什么问题?谢谢! - TheDevMan
我认为它应该是这样的:double lng = t * (toPosition.longitude - startpos.longitude) + startpos.longitude; 如果你仔细想一下...插值从零开始到1。所以当你得到零时,公式变成了0 *(toposition.longitude-startpos.longitude)+ startpos.longitude = startpos.longitude,当你用1进行插值时,公式等于结束位置。1 * toposition.longitude-1 * startpos.longitude + startpos.longitude = toposition.longitude。祝你好运。尝试使用更豪华的acceloratedecelorateinterpolator。祝你好运。 - danny117
@TheDevMan,你找到解决方案了吗? - AKASH WANGALWAR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接