高德地图-地图中心固定Marker,Marker跳跃、掉落、生长动画

1.关键代码:

在移动或者缩放地图的动作结束时,都会进 onCameraChangeFinish 回调中,获取此时的相机座标作为 Marker 的座标。

aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {

        }

        @Override
        public void onCameraChangeFinish(CameraPosition cameraPosition) {
        //cameraPosition是屏幕中心的位置信息
            if (!isItemClickAction) {
                locationMarker.setPosition(cameraPosition.target);
            }
        }
    });

2.实现大头针的跳动动画:

    /**
     * marker点击时跳动一下
     */
    public void jumpPoint(final Marker marker) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        Projection proj = aMap.getProjection();
        final LatLng markerLatlng = marker.getPosition();
        Point markerPoint = proj.toScreenLocation(markerLatlng);
        markerPoint.offset(0, -100);
        final LatLng startLatLng = proj.fromScreenLocation(markerPoint);
        final long duration = 1500;

        final Interpolator interpolator = new BounceInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
                double lng = t * markerLatlng.longitude + (1 - t)
                        * startLatLng.longitude;
                double lat = t * markerLatlng.latitude + (1 - t)
                        * startLatLng.latitude;
                marker.setPosition(new LatLng(lat, lng));
                if (t < 1.0) {
                    handler.postDelayed(this, 16);
                }
            }
        });
    }
里面有一个final Interpolator interpolator = new BounceInterpolator();
就是这个使它达到跳动的效果
以下是它可以达到的所有效果,对于动画的点,可以自己改一下
  AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
  AccelerateInterpolator  在动画开始的地方速率改变比较慢,然后开始加速
  AnticipateInterpolator 开始的时候向后然后向前甩
  AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
  BounceInterpolator   动画结束的时候弹起
  CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
  DecelerateInterpolator 在动画开始的地方快然后慢
  LinearInterpolator   以常量速率改变
  OvershootInterpolator    向前甩一定值后再回到原来位置

3.掉落动画

//掉下来还回弹一次  
private void dropInto(final Marker marker) {

                final Handler handler = new Handler();
                final long start = SystemClock.uptimeMillis();
                final LatLng markerLatlng = marker.getPosition();
                Projection proj = aMap.getProjection();
                Point markerPoint = proj.toScreenLocation(markerLatlng);
                Point startPoint = new Point(markerPoint.x, 0);// 从marker的屏幕上方下落
                final LatLng startLatLng = proj.fromScreenLocation(startPoint);
                final long duration = 800;// 动画总时长

                final Interpolator interpolator = new AccelerateInterpolator();
                handler.post(new Runnable() {
                        @Override
                        public void run() {
                                long elapsed = SystemClock.uptimeMillis() - start;
                                float t = interpolator.getInterpolation((float) elapsed
                                                / duration);
                                double lng = t * markerLatlng.longitude + (1 - t)
                                                * startLatLng.longitude;
                                double lat = t * markerLatlng.latitude + (1 - t)
                                                * startLatLng.latitude;
                                marker.setPosition(new LatLng(lat, lng));
                                if (t < 1.0) {
                                        handler.postDelayed(this, 16);
                                }
                        }
                });
        }

4.从地上生长动画

/**
     * 从地上生长效果,实现思路
     * 在较短的时间内,修改marker的图标大小,从而实现动画
     * 1.保存原始的图片;
     * 2.在原始图片上缩放得到新的图片,并设置给marker;
     * 3.回收上一张缩放后的图片资源;
     * 4.重复2,3步骤到时间结束;
     * 5.回收上一张缩放后的图片资源,设置marker的图标为最原始的图片;
     * 
     * 其中时间变化由AccelerateInterpolator控制
     * @param marker
     */
    private void growInto(final Marker marker) {
        marker.setVisible(false);
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final long duration = 250;// 动画总时长
        final Bitmap bitMap = marker.getIcons().get(0).getBitmap();// BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
        final int width = bitMap.getWidth();
        final int height = bitMap.getHeight();

        final Interpolator interpolator = new AccelerateInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);

                if (t > 1) {
                    t = 1;
                }

                // 计算缩放比例
                int scaleWidth = (int) (t * width);
                int scaleHeight = (int) (t * height);
                if (scaleWidth > 0 && scaleHeight > 0) {

                    // 使用最原始的图片进行大小计算
                    marker.setIcon(BitmapDescriptorFactory.fromBitmap(Bitmap
                            .createScaledBitmap(bitMap, scaleWidth,
                                    scaleHeight, true)));
                    marker.setVisible(true);

                    // 因为替换了新的图片,所以把旧的图片销毁掉,注意在设置新的图片之后再销毁
                    if (lastMarkerBitMap != null
                            && !lastMarkerBitMap.isRecycled()) {
                        lastMarkerBitMap.recycle();
                    }

                    //第一次得到的缩放图片,在第二次回收,最后一次的缩放图片,在动画结束时回收
                    ArrayList<BitmapDescriptor> list = marker.getIcons();
                    if (list != null && list.size() > 0) {
                        // 保存旧的图片
                        lastMarkerBitMap = marker.getIcons().get(0).getBitmap();
                    }

                }

                if (t < 1.0 && count < 10) {
                    handler.postDelayed(this, 16);
                } else {
                    // 动画结束回收缩放图片,并还原最原始的图片
                    if (lastMarkerBitMap != null
                            && !lastMarkerBitMap.isRecycled()) {
                        lastMarkerBitMap.recycle();
                    }
                    marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitMap));
                    marker.setVisible(true);
                }
            }
        });
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章