1. 程式人生 > >高德地圖之拾取地點

高德地圖之拾取地點

高德地圖官方有API,有文件,但是大家懂的,有些東西並沒有說明。所以,我打算將自己實現對高德地圖展示、定位以及導航的功能步驟做一個總結,分享給大家。本文作為總結高德地圖使用,首先總結自己對於拾取地點這樣的功能的實現。

第一步,準備工作:

首先,我們需要去高德地圖獲取key,然後下載sdk(包括jar包和so檔案),本專案需要的sdk,如圖:

這裡寫圖片描述

當我們將key下載好以後,並且將jar包和so檔案放好——建議直接將jar包放在libs資料夾,然後將so檔案放在jinLibs資料夾下面,當然,我們也可以將so檔案也放到libs,然後將Module的build.gradle檔案修改如圖:

這裡寫圖片描述

接下來就是修改檔案清單,這些我們可以直接將API的程式碼複製過來了:

//地圖包、搜尋包、定位包、導航包需要的基礎許可權
<!--允許程式開啟網路套接字-->
<uses-permission android:name="android.permission.INTERNET" />  
<!--允許程式設定內建sd卡的寫許可權-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    
<!--允許程式獲取網路狀態-->
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允許程式訪問WiFi網路資訊--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!--允許程式讀寫手機狀態和身份--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--允許程式訪問CellID或WiFi熱點來獲取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!--用於訪問GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!--這個許可權用於允許程式在手機螢幕關閉後後臺程序仍然執行--> <user-permission android:name="android.permission.WAKE_LOCK"/> <application android:icon="@drawable/icon" android:label="@string/app_name" > <meta-data android:name="com.amap.api.v2.apikey" android:value="e969e70f8daf003d370ab982e6ba656d"/> …… <service android:name="com.amap.api.location.APSService"></service> </application>

準備工作的最後一步只需要執行sync project with gradle files就完成整個專案的準備工作了!
準備工作完成了,我們接下來就執行第二步,展示地圖:
首先,我們需要佈局中有一個地圖的佈局,程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.amap.api.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>




</LinearLayout>

接下來就是對於地圖的呼叫,這個非常簡單,API裡面都是現成的,程式碼如下:

public class PiclocationActivity extends Activity {

    private MapView mMapView = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_piclocation);
        ActionBar actionBar = getActionBar();
        if(actionBar!=null)actionBar.hide();
        mMapView = (MapView) findViewById(R.id.map);
        mMapView.onCreate(savedInstanceState);// 此方法必須重寫

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),銷燬地圖
        mMapView.onDestroy();
    }
    @Override
    protected void onResume() {
        super.onResume();
        //在activity執行onResume時執行mMapView.onResume (),重新繪製載入地圖
        mMapView.onResume();
    }
    @Override
    protected void onPause() {
        super.onPause();
        //在activity執行onPause時執行mMapView.onPause (),暫停地圖的繪製
        mMapView.onPause();
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity執行onSaveInstanceState時執行mMapView.onSaveInstanceState (outState),儲存地圖當前的狀態
        mMapView.onSaveInstanceState(outState);
    }



}

於是地圖就展示出來了。

這裡寫圖片描述

當然,如果你是你現在看到的地圖是沒有中間的圖示,位置也應該是北京為中心點的地圖。而我們今天需要實現的是拾取座標點,所以必須要顯示當前定位的。而關於地圖展示的相關方法,接下來還會用的到。所以,我們接下來就實現上面的效果吧!

第二步,開始定位:

其實,這個也程式碼量也非常簡單,如下:

 private AMap amap;
 private OnLocationChangedListener mListener;
 private AMapLocationClient mlocationClient;
 private AMapLocationClientOption mLocationOption;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
       ...
        initMap();

    }

    /**
     * 地圖例項化
     */
    private void initMap() {
        if (amap == null) {
            amap = mMapView.getMap();
            amap.setLocationSource(this);//設定了定位的監聽,這裡要實現LocationSource介面
            amap.getUiSettings().setMyLocationButtonEnabled(true); // 是否顯示定位按鈕
            amap.setMyLocationEnabled(true);//顯示定位層並且可以觸發定位,預設是flase
        }
 /**
     * 啟用定位
     */
 @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (mlocationClient == null) {
            //初始化定位
            mlocationClient = new AMapLocationClient(this);
            //初始化定位引數
            mLocationOption = new AMapLocationClientOption();
            //設定定位回撥監聽
            mlocationClient.setLocationListener(this);
            //設定為高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //設定為定位一次
//            mLocationOption.setOnceLocation(true);
            //設定定位引數
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網路流量消耗,
            // 注意設定合適的定位時間的間隔(最小間隔支援為2000ms),並且在合適時間呼叫stopLocation()方法來取消定位請求
            // 在定位結束後,在合適的生命週期呼叫onDestroy()方法
            // 在單次定位情況下,定位無論成功與否,都無需呼叫stopLocation()方法移除請求,定位sdk內部會移除
            mlocationClient.startLocation();//啟動定位
        }
    }
/**
     * 登出定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }
/**
     * 實現定位
     * @param amapLocation
     */
@Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    &&amapLocation.getErrorCode() == 0) {
               String location = "當前地點:"+amapLocation.getProvider()+amapLocation.getCity()+amapLocation.getStreet()+amapLocation.getStreetNum();
                Log.d(TAG, "onLocationChanged: ");
            } else {
                String errText = "定位失敗," + amapLocation.getErrorCode()+ ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr",errText);
            }
        }
    }

接下來我們看看這個效果,首先看看日誌:

04-29 23:53:04.267 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:06.268 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:08.270 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:10.277 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:12.327 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:14.281 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:16.282 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:18.288 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:20.297 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:22.291 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:24.640 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:26.295 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:28.301 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:30.298 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:32.303 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:34.304 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:36.352 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:38.339 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:40.340 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段71204-29 23:53:42.341 18491-18491/cn.com.vicent.mymap D/PiclocationActivity: onLocationChanged: 當前地點:lbs成都市劍南大道南段712

定位這麼多次沒有問題,但是地圖並沒有顯示,why?

這裡寫圖片描述

那我們現在將地圖定位成功這個方法增加一句程式碼,實現地圖顯示當前位置:

mListener.onLocationChanged(amapLocation);// 顯示系統小藍點

其實上面還有一個問題,就是地圖顯示的縮放級別不一樣,對吧?所以我們還需要在地圖顯示的時候預先設定縮放級別(程度).程式碼如下:

 /**
     * 地圖例項化
     */
    private void initMap() {
        if (amap == null) {
            ...
            amap.moveCamera(CameraUpdateFactory.zoomTo(15));//設定地圖縮放級別
        }
    }

接下來我們看看效果:

這裡寫圖片描述

這個效果已經基本成型了,但是我們還需要修改一下地圖中心點的圖示,我們不要圓形及邊框,接下來看看程式碼:

/**
     * 地圖例項化
     */
    private void initMap() {
        if (amap == null) {
            ...
            MyLocationStyle myLocationStyle = new MyLocationStyle();//初始化定位藍點樣式類
            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);//連續定位、且將視角移動到地圖中心點,定位點依照裝置方向旋轉,並且會跟隨裝置移動。(1秒1次定位)如果不設定myLocationType,預設也會執行此種模式。
            myLocationStyle.strokeColor(Color.TRANSPARENT);//設定定位藍點精度圓圈的邊框顏色
            myLocationStyle.radiusFillColor(Color.TRANSPARENT);//設定定位藍點精度圓圈的填充顏色
            amap.setMyLocationStyle(myLocationStyle);//設定定位藍點的Style
        }
    }

OK,搞定!接下來,就要開始放大招了!我們需要點選螢幕的時候,顯示當前位置以及周邊的位置,實現高德地圖這樣的效果:

這裡寫圖片描述

需要實現上述效果,這裡需要實現幾點功能:

  1. 定位(已經實現)
  2. 周邊搜尋(下一步需要實現)
  3. 手指滑動地圖停止的時候獲取位置——逆地理編碼(下下一步需要實現)
  4. 將結果以列表的形式展現出來

於是我們接著上面的內容,開始進行第三步,周邊搜尋。

第三步,周邊搜尋:

API裡面介紹周邊搜尋叫做“獲取POI資料”,並且有六種方式,如下:

  • 根據關鍵字檢索POI
  • 檢索周邊POI
  • 檢索多邊形內的POI
  • 根據ID檢索POI
  • 根據輸入自動提示
  • 獲取道路沿途的POI資料

因為我們需要的是周圍的資料,所以這裡我們選擇第二種,這種情況比較合適。程式碼如下:

 /**
     * 周邊資料實體封裝
     */
    private class ListViewHoldier{
        String title;
        String address;
        LatLonPoint lp;
    }

private List<ListViewHoldier> data = new ArrayList<>();
//第一個位置資料,設為成員變數是因為有多個地方需要使用
    private ListViewHoldier lvHolder;
 /**
     * 地圖例項化
     */
    private void initMap() {
        ...
            lvHolder = new ListViewHoldier();
        ...
    }
 /**
     * 實現定位
     * @param amapLocation
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    &&amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);// 顯示系統小藍點
                if(lvHolder.title==null){//只要第一次的資料,否則第一項的位置始終不會變。當然,也可以在這裡關閉定位
//                    mlocationClient.stopLocation();//停止定位
                    lvHolder.title = "[位置]";
                    //關於定位資料,可以檢視API http://lbs.amap.com/api/android-location-sdk/guide/android-location/getlocation
                    lvHolder.address = amapLocation.getProvider()+amapLocation.getCity()+amapLocation.getStreet()+amapLocation.getStreetNum();
                    lvHolder.lp = new LatLonPoint(amapLocation.getLatitude(),amapLocation.getLongitude());
                    data.add(0,lvHolder);
                    doSearchQuery();
                }

            } else {
                String errText = "定位失敗," + amapLocation.getErrorCode()+ ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr",errText);
            }
        }
    }
    /**
     * 搜查周邊資料
     */
    private void doSearchQuery() {
        //搜尋型別
        String type = "汽車服務|汽車銷售|" +
                "汽車維修|摩托車服務|餐飲服務|購物服務|生活服務|體育休閒服務|醫療保健服務|" +
                "住宿服務|風景名勝|商務住宅|政府機構及社會團體|科教文化服務|交通設施服務|" +
                "金融保險服務|公司企業|道路附屬設施|地名地址資訊|公共設施";
        query = new PoiSearch.Query("", type, "");// 第一個引數表示搜尋字串,第二個引數表示poi搜尋型別,第三個引數表示poi搜尋區域(空字串代表全國)
        query.setPageSize(20);// 設定每頁最多返回多少條poiitem
        query.setPageNum(0);// 設定查第一頁

        poiSearch = new PoiSearch(this, query);
        //搜尋回撥
        poiSearch.setOnPoiSearchListener(this);
        //搜尋位置及範圍
        poiSearch.setBound(new PoiSearch.SearchBound(lvHolder.lp, 1000));
        //同步搜尋
//        poiSearch.searchPOI();//不能在主執行緒實現耗時操作
        //非同步搜尋
        poiSearch.searchPOIAsyn();
    }
     /**
     * 返回POI搜尋非同步處理的結果。
     * @param result
     * @param rcode
     */
    @Override
    public void onPoiSearched(PoiResult result, int rcode) {
        if (rcode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getQuery() != null) {// 搜尋poi的結果
                if (result.getQuery().equals(query)) {// 是否是同一條
                    // 取得搜尋到的poiitems有多少頁
                    List<PoiItem> poiItems = result.getPois();// 取得第一頁的poiitem資料,頁數從數字0開始
                    if (poiItems != null && poiItems.size() > 0) {
                        for (int i = 0;i<poiItems.size();i++){
                            PoiItem poiitem = poiItems.get(i);
                            ListViewHoldier holder = new ListViewHoldier();
                            holder.address = poiitem.getSnippet();
                            holder.title = poiitem.getTitle();
                            holder.lp = poiitem.getLatLonPoint();
                            if(data.size()>i+1){
                                data.remove(i+1);
                            }
                            data.add(i+1,holder);
                            Log.d(TAG, "onPoiSearched: \n"+holder.address+"\n"+holder.title+"\n"+holder.lp.toString());
                        }

                    } else {

                    }
                }
            } else {

            }
        } else {

        }
    }

    /**
     * poi id搜尋的結果回撥
     * @param poiItem
     * @param i
     */
    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

OK,程式碼比較長,我們接下來看看日誌輸出結果,檢驗一下我們的成果,日誌如下:

04-30 12:12:39.010 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段
                                                                          小勇矽膠
                                                                          30.528865,104.044311
04-30 12:12:39.010 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段698號附11號
                                                                          老草屋燒烤(華陽店)
                                                                          30.528869,104.044336
04-30 12:12:39.010 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          協和街道劍南大道南段712號
                                                                          華宜·上錦
                                                                          30.528781,104.044425
04-30 12:12:39.010 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段
                                                                          依愛思洗衣
                                                                          30.528873,104.044673
04-30 12:12:39.010 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          協和街道劍南大道南段698號附8號
                                                                          子墨西點
                                                                          30.52902,104.04488
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段708-710號附近
                                                                          樂誠家樂(劍南大道南段)
                                                                          30.528738,104.044926
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          協和街道劍南大道南段706號
                                                                          大邑血旺家常菜
                                                                          30.528702,104.045092
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段708-710號附近
                                                                          欣家超市
                                                                          30.528637,104.04507
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段708-710
                                                                          美家裝飾建材(華陽店)
                                                                          30.528752,104.045118
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段706號附近
                                                                          貝爾康藥業(同福堂大藥房)
                                                                          30.528835,104.045141
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段美家建材旁
                                                                          牛肉麵&餛飩王&黃燜雞米飯(劍南大道店)
                                                                          30.528964,104.045165
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          雙流區
                                                                          元景路與劍南大道南段交叉口
                                                                          30.529386,104.045866
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          515;521路;814路
                                                                          劍南大道元景路口站(公交站)
                                                                          30.529922,104.045593
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          天府新區華府大道一段996號(金茂)光明城市54單元
                                                                          菜鳥驛站(光明城市優超市周6寄件免費)
                                                                          30.5273,104.04558
04-30 12:12:39.020 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          元景路與劍南大道南段交叉口東100米
                                                                          停車場(元景路)
                                                                          30.529275,104.046573
04-30 12:12:39.030 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          G123路;T207路
                                                                          元景路劍南大道口站(公交站)
                                                                          30.529392,104.046562
04-30 12:12:39.030 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          元景路金茂光明城市3號門124單元2層
                                                                          海鳴畫室二號店
                                                                          30.529139,104.046657
04-30 12:12:39.030 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          劍南大道南段
                                                                          順發超市
                                                                          30.531082,104.044417
04-30 12:12:39.030 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          華陽鎮劍南大道南段688號
                                                                          騎龍小區
                                                                          30.526689,104.043652
04-30 12:12:39.030 18831-18831/cn.com.vicent.mymap D/PiclocationActivity: onPoiSearched: 
                                                                          華陽華府大道一段99611攝影工作室
                                                                          30.527685,104.046519

OK,周邊搜尋已經搞定,接下來執行下一步。

第四步,隨手指的滑動更新資料:

其實上面有一個bug,就是我們手指滑動是時候,然後定位成功就會將地圖的中心點重新定位會我們當前的位置,如圖:

這裡寫圖片描述

原因是高德地圖預設每秒更新一次當前位置,所以每秒地圖就會回到中心點一次。解決方法很多,可以關閉定位,或者將定位成功後的顯示系統小藍點給關掉,程式碼如下:

mListener.onLocationChanged(amapLocation);// 顯示系統小藍點

現在我們的地圖還只是可以隨意滑動,但是我們需要在手指滑動結束的時候獲取到經緯度,然後更新我們的周邊資料。更新周邊的資料已經封裝好一個方法了,問題是在手指滑動的時候獲取到經緯度。並且,在開啟地圖的時候中心點覆蓋系統圖標上面還有一個圖示,並且該圖示隨手指移動,在手指結束滑動的時候還有一個動畫。所以整理一下思路,接下來需要實現的有如下幾點:

  1. 開啟地圖的時候顯示自定義圖示
  2. 圖示隨手指移動
  3. 手指移動結束的時候圖示有一個動畫
  4. 手指移動結束的時候獲取到當前的經緯度並且更新資料

首先我們來實現對地圖新增自定義圖示,程式碼如下:

private Marker mEndMarker;
 /**
     * 實現定位
     * @param amapLocation
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
      ...
                    // 初始化Marker新增到地圖
                    mEndMarker = amap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.end))));
                    mEndMarker.setPosition(new LatLng(amapLocation.getLatitude(),amapLocation.getLongitude()));
                    ...
    }

完成了第1步,接下來實現第2步,就是手指滑動的時候圖示隨手指滑動。這裡我們需要實現一個地圖狀態發生變化的監聽介面——AMap.OnCameraChangeListener,它有兩個抽象方法,如下:

 /**
     * 地圖例項化
     */
    private void initMap() {
        if (amap == null) {
        ...
            amap.setOnCameraChangeListener(this);
        }
    }
/**
     * 在地圖狀態改變過程中回撥此方法。
     * @param cameraPosition
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        mEndMarker.setPosition(cameraPosition.target);
    }

    /**
     * 在地圖狀態改變完成時回撥此方法。
     * @param cameraPosition
     */
    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {

    }

接下來實現第3步,在滑動結束時啟動一個動畫。所以我們直接在onCameraChangeFinish(CameraPosition cameraPosition)方法裡面執行動畫的方法即可,程式碼如下:

 /**
     * 在地圖狀態改變完成時回撥此方法。
     * @param cameraPosition
     */
    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {

        jumpPoint(mEndMarker);
    }

    /**
     * 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, -50);
        final LatLng startLatLng = proj.fromScreenLocation(markerPoint);
        final long duration = 500;

        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);
                }
            }
        });
    }

上面這些比較花哨的動作完成以後,我們得幹一點實事,就是獲取資料,並且及時更新。首先,我們需要在手指滑動結束的時候獲取到經緯度,然後通過逆地理編碼方法拿到地址的詳細資料,再接著通過經緯度查詢周邊資料。所以這1步其實有三個動作。我們就不一步步的列了,直接上程式碼,看註釋:

 /**
     * 逆地理編碼業務類
     */