在mapview上平滑地设置摄像机路径的动画

时间:2013-06-12 16:03:44

标签: android google-maps camera android-mapview android-maps-v2

我使用我的MapView(新API v2)以及属于路线的点列表。他们非常接近。我的问题是,如果我做动画步骤调用

        mMapInstance.animateCamera(CameraUpdateFactory.newLatLng(mNextPosition),ms, null);

摄像师表现得像一只强悍的蚱蜢,夸张地夸张地说,在这个过程中幻灯片缓存得到了@ ## @#@#!

制作路径动画并获得统一滚动体验的最佳方法是什么?速度不是问题,我会用低速,我对平滑感兴趣...

如果我可以模拟我用手指做的路径,我会非常高兴..因为地图表现得很漂亮并且有很多瓷砖围绕缓存。但是,任何以编程方式移动地图的尝试都会产生粗体动画,白色屏幕,重新加载图块......

提前致谢!!!

2 个答案:

答案 0 :(得分:4)

我发现使用可选的回调作为最终参数来表示递归解决方案可以提供平滑的动画。此代码放大,更改全景旋转的角度,然后再次放大;但是,当初始参数和初始回调相同时,它不喜欢它;我确信有更好的方法来调用递归,但希望这可以让你了解如何在功能上进行动画制作:

    //initial zoom
static final int initZoom = 8;
//steps the zoom
int stepZoom = 0;
// number of steps in zoom, be careful with this number!
int stepZoomMax = 5;
//number of .zoom steps in a step
int stepZoomDetent = (18 - initZoom) / stepZoomMax;
//when topause zoom for spin
int stepToSpin = 4;
//steps the spin
int stepSpin = 0;
//number of steps in spin (factor of 360)
int stepSpinMax = 4;
//number of degrees in stepSpin
int stepSpinDetent = 360 / stepSpinMax;

Intent detailIntent;
Intent intent;  
Marker marker;
final int mapHopDelay = 2000;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_affirm);
    try
    {MapsInitializer.initialize(this);}
    catch (GooglePlayServicesNotAvailableException impossible)
    {   /* Impossible */ Log.e(TAG, "the impossible occurred");}
    intent = this.getIntent();
    latLng = new LatLng(intent.getDoubleExtra("Latitude", 0.0), intent.getDoubleExtra("Longitude", 0.0));
    map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
    map.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                                                            .target(latLng)
                                                            .zoom(initZoom-1)
                                                            .build())
                      , mapHopDelay
                      , cameraAnimation
                      );
    marker = map.addMarker(new MarkerOptions()
                           .draggable(true)
                           .position(latLng)
                           .title("Location of Photographer"));

}

public CancelableCallback cameraAnimation = new CancelableCallback(){

    @Override
    public void onFinish()
    {
        if (stepZoom < stepZoomMax && stepZoom != stepToSpin)
        {
            stepZoom++;
            map.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                                                                    .target(latLng)
                                                                    .zoom(initZoom + (stepZoomDetent * (stepZoom - 1)))
                                                                    //   .bearing(40*aniStep)
                                                                    //   .tilt(60)
                                                                    .build()), mapHopDelay, cameraAnimation);

        }
        else if (stepZoom >= stepZoomMax)// ending position hard coded for this application
        {map.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                                                                 .target(latLng)
                                                                 .zoom(18)
                                                                 //  .bearing(0)
                                                                 .tilt(0)
                                                                 .build()));
        }
        else
        {
            if (stepSpin <= stepSpinMax)
            {
                stepSpin++;
                map.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                                                                        .target(latLng)
                                                                        .zoom(initZoom + stepZoomDetent * stepZoom)
                                                                        .bearing(stepSpinDetent * (stepSpin - 1))
                                                                        .tilt(60)
                                                                        .build()), mapHopDelay, cameraAnimation);
            }
            else
            {
                stepZoom++;
                map.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                                                                        .target(latLng)
                                                                        .zoom(initZoom + stepZoomDetent * stepZoom)
                                                                        .bearing(0)
                                                                        .tilt(0)
                                                                        .build()), mapHopDelay, cameraAnimation);
            }
        }
    }

    @Override
    public void onCancel()
    {}

};

答案 1 :(得分:1)

好吧,我希望有人提供更好的答案,但是通过我做过的许多实验,我无法使用animateCamera获得一个不错的平滑滚动。

无论只是将Lat / Lng改变为靠近的点,摄影师一直在进行令人印象深刻的起飞和着陆。

我通过以下程序获得了有限的'el-cheapo'动画成功:

    private void animateTo(double lat, double lon, double zoom, double bearing, double tilt, final int milliseconds) {

        if (mMapInstance==null) return;
        mMapInstance.setMapType(paramMapMode);
        mCurrentPosition=new LatLng(lat,lon);

        // animate camera jumps too much
        // so we set the camera instantly to the next point

        mMapInstance.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(mCurrentPosition,(float)zoom, (float)tilt, (float)bearing)));

        // give Android a break so it can load tiles. If I start the animation
        // without pause, no tile loading is done

        mMap.postDelayed(new Runnable(){
            @Override
            public void run() {
                // keeping numbers small you get a nice scrolling effect
                mMapInstance.animateCamera(CameraUpdateFactory.scrollBy(250-(float)Math.random()*500-250, 250-(float)Math.random()*500),milliseconds,null);

            }},500);

    }

此例程在10000s中以毫秒值调用,转到一个点,然后在随机方向上制作一个天桥动画,保持该死的变焦平静。由于像素值非常小,很有可能 一切都缓存了。

有没有更好的解决方案?尝试注入触摸事件来模拟“触摸”的投掷是否合理或可能?