1. 程式人生 > >高德地圖-地圖中心固定Marker,Marker跳躍、掉落、生長動畫

高德地圖-地圖中心固定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);
                }
            }
        });
    }