Android平台高德API经验:长按地图获取位置信息
操作方法
- 01
Android 开发过程中,有很多手势操作都很让人又爱又恨。一方面可以更便捷的体现更多功能,提升应用的体验,一方面繁复多变的操作背后有着许多开发技巧和难题。这里分享一个长按地图获取位置信息的手势。 为了更明了,先上个展示效果:长按地图某点显示该点地理位置信息功能 通过构造一个locationSelectOverlay类来定义该功能,在地图上对长按手势进行监听,一旦有这个事件发生就调用getAddressFromServer()方法来显示地址信息。 在该工程中分别定义4个类longPressMap.java,locationSelectOverlay.java,popUpPanel.java,Constants.java longPressMap.java为显示一个地图类,通过实例化一个locationSelectOverlay类实现长按地图显示地理位置信息功能代码如下: //longPressMap 类继承MapActivity对mapview资源进行管理 public class longPressMap extends MapActivity { private MapView mMapView; locationSelectOverlay mSelectLay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //使用setContentView方法调用R.layout.activity_regeocoder布局文件,显示地图 setContentView(R.layout.geocoder); //获取地图视图的id,赋值给mMapView mMapView = ((MapView) findViewById(R.id.geocode_MapView)); // 设置启用内置的缩放控件 mMapView.setBuiltInZoomControls(true); //实例化一个locationSelectOverlay类 mSelectLay = new locationSelectOverlay(this, mMapView, new popUpPanel(this, mMapView)); //将该功能加载到此地图上,启用长按地图显示该点地址信息的功能 mMapView.getOverlays().add(mSelectLay); } } 复制代码 locationSelectOverlay 示例代码如下: //locationSelectOverlay类继承Overlay接口,实现OnGestureListener手势监听 public class locationSelectOverlay extends Overlay implements OnGestureListener { public popUpPanel mTipPanel; //声明一个弹出框对象 GeoPoint mSelectPoint; //声明一个地理坐标点对象 MapView mMapView; //声明一个地图视图对象 Context mContext; //活动对象 TextView mTipText=null; //声明一个文本对象 private static String nearbystr=""; private GestureDetector gestureScanner; //声明一个手势监听对象 private Geocoder coder; //声明一个逆地理编码对象 private String addressName=""; //声明一个地址名称字符串 //长按地图某点获取信息的构造函数。 public locationSelectOverlay(Activity context,MapView mapView,popUpPanel panel) { this.mContext=context; this.mMapView=mapView; this.mTipPanel=panel; gestureScanner = new GestureDetector(this); //声明一个手势监听对象 coder = new Geocoder(context); //声明一个逆地理编码对象 } //用Handler函数处理传递来的地址信息,显示在文本框中 private Handler mGeocoderHandler = new Handler() { public void handleMessage(Message msg) { //如果有地址信息的消息发送过来,将文本框中设置为该地址信息 if(msg.what == Constants.REOCODER_RESULT) { if(mTipText!=null) mTipText.setText(addressName); } //如果显示错误,则文本框中设置报错信息 else if(msg.what == Constants.ERROR) { Toast.makeText(mContext, "获取地址失败,请重试", Toast.LENGTH_SHORT).show(); removeTipPanel(); } } }; //显示弹出窗口 public boolean showTap(GeoPoint p) { View view = mTipPanel.getView(); mMapView.removeView(view); //布局参数设置 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; } //从经纬度坐标点获取对应的地址信息 public void getAddressFromServer(final GeoPoint point,final Handler handler) { //声明一个线程 new Thread(){ public void run() { try { // 逆地理编码getFromLocation()函数获取该点对应的前3个地址信息 List<Address> address = coder.getFromLocation((double)point.getLatitudeE6()/1E6, (double)point.getLongitudeE6()/1E6, 3); if (address != null) { //获取第一个地址信息 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 block handler.sendMessage(Message .obtain(handler, Constants.ERROR)); } } }.start(); //线程启动 } //移走弹出窗口 public void removeTipPanel() { View view = mTipPanel.getView(); mMapView.removeView(view); } //获取手势操作 public boolean onTouchEvent(MotionEvent event, MapView mapView) { return gestureScanner.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub return false; } //长按地图,弹出提示框,显示该点地址信息 @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub int x = (int)e.getX(); int y = (int)e.getY(); mSelectPoint = mMapView.getProjection().fromPixels(x, y); //调用显示提示框函数 showTap(mSelectPoint); //调用从经纬度点获取地址信息函数 getAddressFromServer(mSelectPoint,mGeocoderHandler); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } 复制代码 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(); //设置弹出的视图是id为R.layout.activity_long_press_map的视图 this.popup = paramActivity.getLayoutInflater().inflate(R.layout.activity_long_press_map, localViewGroup, false); … 复制代码 Constants 定义了传递的常量对应的值,如public static finalint REOCODER_RESULT=3000; 表示逆地理编码结果常量,public staticfinal int ERROR=1001; 表示出现错误常量。