中,有很多手勢(shì)操作都很讓人又愛又恨。一方面可以更便捷的體現(xiàn)更多功能,提升應(yīng)用的體驗(yàn),一方面繁復(fù)多變的操作背后有著許多開發(fā)技巧和難題。這里分享一個(gè)長(zhǎng)按地圖獲取位置信息的手勢(shì)。為了更明了,先上個(gè)展示效果:長(zhǎng)按地圖某點(diǎn)顯示該點(diǎn)地理位置信息功能通過構(gòu)造一個(gè)locationSelectOverlay類來定義該功能,在地圖上對(duì)長(zhǎng)按手勢(shì)進(jìn)行監(jiān)聽,一旦有這個(gè)發(fā)生就調(diào)用getAddressFromServer()方法來顯示地址信息。在該工程中分別定義4個(gè)類longPressMap.java,locationSelectOverlay.java,popUpPanel.java,Constants.javalongPressMap.java 為顯示一個(gè)地圖類,通過實(shí)例化一個(gè)locationSelectOverlay類實(shí)現(xiàn)長(zhǎng)按地圖顯示地理位置信息功能代碼如下://longPressMap 類繼承MapActivity對(duì)mapview資源進(jìn)行管理public class longPressMap extends MapActivity {private MapView mMapView;locationSelectOverlay mSelectLay;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//使用setContentView方法調(diào)用R.layout.activity_regeocoder布局文件,顯示地圖setContentView(R.layout.geocoder);//獲取地圖視圖的id,賦值給mMapView mMapView = ((MapView) findViewById(R.id.geocode_MapView));// 設(shè)置啟用內(nèi)置的縮放控件mMapView.setBuiltInZoomControls(true); //實(shí)例化一個(gè)locationSelectOverlay類mSelectLay = new locationSelectOverlay(this, mMapView, new popUpPanel(this, mMapView));//將該功能加載到此地圖上,啟用長(zhǎng)按地圖顯示該點(diǎn)地址信息的功能mMapView.getOverlays().add(mSelectLay);} }復(fù)制代碼locationSelectOverlay 示例代碼如下://locationSelectOverlay類繼承Overlay接口,實(shí)現(xiàn)OnGestureListener手勢(shì)監(jiān)聽public class locationSelectOverlay extends Overlay implements OnGestureListener {public popUpPanel mTipPanel; //聲明一個(gè)彈出框?qū)ο驡eoPoint mSelectPoint; //聲明一個(gè)地理坐標(biāo)點(diǎn)對(duì)象MapView mMapView; //聲明一個(gè)地圖視圖對(duì)象Context mContext; //活動(dòng)對(duì)象TextView mTipText=null; //聲明一個(gè)文本對(duì)象private static String nearbystr="";private GestureDetector gestureScanner; //聲明一個(gè)手勢(shì)監(jiān)聽對(duì)象private Geocoder coder; //聲明一個(gè)逆地理編碼對(duì)象private String addressName=""; //聲明一個(gè)地址名稱字符串//長(zhǎng)按地圖某點(diǎn)獲取信息的構(gòu)造函數(shù)。public locationSelectOverlay(Activity context,MapView mapView,popUpPanel panel){this.mContext=context; this.mMapView=mapView;this.mTipPanel=panel; gestureScanner = new GestureDetector(this); //聲明一個(gè)手勢(shì)監(jiān)聽對(duì)象coder = new Geocoder(context); //聲明一個(gè)逆地理編碼對(duì)象}//用Handler函數(shù)處理傳遞來的地址信息,顯示在文本框中private Handler mGeocoderHandler = new Handler(){public void handleMessage(Message msg){//如果有地址信息的消息發(fā)送過來,將文本框中設(shè)置為該地址信息if(msg.what == Constants.REOCODER_RESULT){if(mTipText!=null)mTipText.setText(addressName);}//如果顯示錯(cuò)誤,則文本框中設(shè)置報(bào)錯(cuò)信息else if(msg.what == Constants.ERROR){Toast.makeText(mContext, "獲取地址失敗,請(qǐng)重試", Toast.LENGTH_SHORT).show();removeTipPanel();}}};//顯示彈出窗口public boolean showTap(GeoPoint p) {View view = mTipPanel.getView();mMapView.removeView(view);//布局參數(shù)設(shè)置MapView.LayoutParams geoLP = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,MapView.LayoutParams.WRAP_CONTENT, p,MapView.LayoutParams.BOTTOM_CENTER);//彈出窗口的文本顯示mTipText = (TextView) view.findViewById(R.id.GeoName);mTipText.setText("正在加載地址...");mTipText.setOnClickListener(new OnClickListener() {public void onClick(View v) {}});//在地圖視圖上添加該彈出窗口視圖mMapView.addView(view, geoLP);return false;}//從經(jīng)緯度坐標(biāo)點(diǎn)獲取對(duì)應(yīng)的地址信息public void getAddressFromServer(final GeoPoint nt,final Handler handler){//聲明一個(gè)線程new Thread(){public void run(){try {// 逆地理編碼getFromLocation()函數(shù)獲取該點(diǎn)對(duì)應(yīng)的前3個(gè)地址信息List<Address> address = coder.getFromLocation((double)nt.getLatitudeE6()/1E6,(double)nt.getLongitudeE6()/1E6, 3);if (address != null) {//獲取第一個(gè)地址信息Address addres = address.get(0);addressName = "";if(addres.getAdminArea()!=null)addressName+=addres.getAdminArea();if(addres.getSubLocality()!=null)addressName += addres.getSubLocality();if(addres.getFeatureName()!=null)addressName += addres.getFeatureName();addressName += "附近";handler.sendMessage(Message.obtain(handler, Constants.REOCODER_RESULT));}} catch (AMapException e) {// TODO Auto-generated catch blockhandler.sendMessage(Message.obtain(handler, Constants.ERROR));}}}.start(); //線程啟動(dòng)}//移走彈出窗口public void removeTipPanel(){ View view = mTipPanel.getView();mMapView.removeView(view);}//獲取手勢(shì)操作public boolean onTouchEvent(MotionEvent event, MapView mapView) {return gestureScanner.onTouchEvent(event);}@Overridepublic boolean onDown(MotionEvent e) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {// TODO Auto-generated method stubreturn false;}//長(zhǎng)按地圖,彈出提示框,顯示該點(diǎn)地址信息@Overridepublic void onLongPress(MotionEvent e) {// TODO Auto-generated method stubint x = (int)e.getX();int y = (int)e.getY();mSelectPoint = mMapView.getProjection().fromPixels(x, y);//調(diào)用顯示提示框函數(shù)showTap(mSelectPoint);//調(diào)用從經(jīng)緯度點(diǎn)獲取地址信息函數(shù)getAddressFromServer(mSelectPoint,mGeocoderHandler);}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY) {// TODO Auto-generated method stubreturn false;}復(fù)制代碼pouUpPanel定義了彈出窗口類public class popUpPanel{private boolean isVisible = false;private MapView mMapView;private View popup;public popUpPanel(Activity paramActivity, MapView paramMapView){this.mMapView = paramMapView;ViewGroup localViewGroup = (ViewGroup)this.mMapView.getParent();//設(shè)置彈出的視圖是id為R.layout.activity_long_press_map的視圖this.popup = paramActivity.getLayoutInflater().inflate(R.layout.activity_long_press_map, localViewGroup, false);…復(fù)制代碼Constants定義了傳遞的常量對(duì)應(yīng)的值,如public static finalint REOCODER_RESULT=3000; 表示逆地理編碼結(jié)果常量,public staticfinal int ERROR=1001; 表示出現(xiàn)錯(cuò)誤常量。