【问题标题】:Smoothly Animating a camera path on a mapview在地图视图上平滑地动画相机路径
【发布时间】:2013-06-12 16:03:43
【问题描述】:

我将 MapView(新 API v2)与属于路线的点列表一起使用。他们非常接近。我的问题是,如果我执行动画步骤调用

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

摄影师表现得像一只勇敢的蚱蜢,夸张地进进出出,在这个过程中,幻灯片缓存会得到@##@#@#!

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

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

提前致谢!!!

【问题讨论】:

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


    【解决方案1】:

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

        //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()
        {}
    
    };
    

    【讨论】:

    • 嗨!听起来很有趣,我没有使用回调,试试看。感谢您发布代码!
    【解决方案2】:

    好吧,我希望有人能提供更好的答案,但是通过我所做的许多实验,我无法使用 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);
    
        }
    

    此例程以 10000 秒的毫秒值调用,到达一个点,然后在随机方向上制作一个飞越动画,保持该死的缩放平静。由于像素值非常小,很可能是 一切都缓存了。

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

    【讨论】:

    • 你不能在mMap上调用postDelayed()
    猜你喜欢
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多