高德地圖-地圖中心固定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);
                }
            }
        });
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章