【问题标题】:How does one implement drag and drop for Android marker?如何实现 Android 标记的拖放?
【发布时间】:2011-04-23 06:46:34
【问题描述】:

喂? 我正在开发 Android 中的 MapView 应用程序。我有三个标记,我希望稍后能够使用 Google Map API getlocation-function。为了尝试一下,我想使用拖放功能移动标记,然后检查位置。

任何已经通过拖放操作来处理 android 标记,或者知道如何开始解决它的人?

/AK

【问题讨论】:

    标签: android drag-and-drop android-mapview marker


    【解决方案1】:

    实现 Google Maps Android API v2,参考:https://developers.google.com/maps/documentation/android/ 并在 GoogleMap 对象上设置 setOnMarkerDragListener。例如:

    map.setOnMarkerDragListener(new OnMarkerDragListener() {
            @Override
            public void onMarkerDragStart(Marker arg0) {
                // TODO Auto-generated method stub
                Log.d("System out", "onMarkerDragStart..."+arg0.getPosition().latitude+"..."+arg0.getPosition().longitude);
            }
    
            @SuppressWarnings("unchecked")
            @Override
            public void onMarkerDragEnd(Marker arg0) {
                // TODO Auto-generated method stub
                Log.d("System out", "onMarkerDragEnd..."+arg0.getPosition().latitude+"..."+arg0.getPosition().longitude);
    
                map.animateCamera(CameraUpdateFactory.newLatLng(arg0.getPosition()));
            }
    
            @Override
            public void onMarkerDrag(Marker arg0) {
                // TODO Auto-generated method stub
                Log.i("System out", "onMarkerDrag...");
            }
        });
    
    //Don't forget to Set draggable(true) to marker, if this not set marker does not drag.
    
    map.addMarker(new MarkerOptions()
        .position(crntLocationLatLng)
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_my_location))
        .draggable(true));
    

    【讨论】:

    • 有什么方法可以在点击时拖动标记而不是长按?
    • 没有。因为点击它会执行 onMarkerClick 以打开标记的信息窗口,这是默认行为,因此我们无法修改此事件。
    • 感谢draggable(true)!直到你提示才发现错误。
    【解决方案2】:

    来自one of my booksHere is a sample project 显示了Android 中Google 地图上标记的拖放移动。

    简而言之,它使用onTouchEvent() 来检测用户何时触摸并将手指靠近标记。然后它从叠加层中删除标记,但使用RelativeLayout 将相同的图像放在地图顶部。然后,在“移动”触摸事件中,图像被移动(比强制整个覆盖重绘更快)。当手指抬起时,图像被移除,但标记被放回覆盖层中的新位置。

    【讨论】:

    • 非常感谢您的链接和解释!我是 Android 新手,所以看看一个运行良好的项目的结构对我来说是一件好事,了解如何真正完成工作,而不仅仅是把东西扔在那里。谢谢。
    • 我认为这已经过时了。 bcoz v2 不支持覆盖。你也有 V2 的东西吗
    • @ShakeebAyaz:请参阅 UrMi 对 Maps V2 方法的回答。此答案适用于原始 Android 地图解决方案 Maps V1。
    【解决方案3】:

    对于 MapsV2。使用谷歌地图事件。不要自己写。

            mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    mVisitingMarker.setPosition(latLng);
                    mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
                }
            });
    
            mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
                @Override
                public void onMarkerDragStart(Marker arg0) {
                }
    
                @SuppressWarnings("unchecked")
                @Override
                public void onMarkerDragEnd(Marker arg0) {
                   Log.d("System out", "onMarkerDragEnd...");
                    mMap.animateCamera(CameraUpdateFactory.newLatLng(arg0.getPosition()));
                }
    
                @Override
                public void onMarkerDrag(Marker arg0) {
                }
            });
    

    【讨论】:

    • 你没有写关于 draggable(true) 的标记。
    【解决方案4】:

    下面是 Kotlin Lover 的答案!这非常简单!如下所示。

       googleMap.addMarker(
            MarkerOptions()
                .position(latLatLng).draggable(true)
        )
    

    下面是获取拖尾位置的内衬代码

       mMap.setOnMarkerDragListener(object : GoogleMap.OnMarkerDragListener {
            override fun onMarkerDragStart(arg0: Marker) {
    
            }
    
            override fun onMarkerDragEnd(arg0: Marker) {
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(arg0.position, 1.0f))
                val message = arg0.position.latitude.toString() + "" + arg0.position.longitude.toString()
                Log.d(TAG + "_END", message)
            }
    
            override fun onMarkerDrag(arg0: Marker?) {
                val message = arg0!!.position.latitude.toString() + "" + arg0.position.longitude.toString()
                Log.d(TAG + "_DRAG", message)
            }
        })
    

    【讨论】:

      【解决方案5】:

      我对 CommonsWare 拖放功能的出色功能进行了一些优化。

      我正在使用地图上的标记进行一些精确测量,并且我希望我的标记准确地位于我触摸并抬起手指的位置,以便测量准确。

      在 CommonsWare 的原件上,如果您触摸“靠近”标记,则标记不会到达那个确切的点,而是随着您手指的移动而移动。 我需要标记出现在 ACTION_DOWN、ACTION_MOVE 和 ACTION_UP 上的手指正下方。

      如果有人需要,这里是代码。必须感谢 CommonsWare 才能实现这个功能,真是个好主意。

      这是我修改的部分代码。

      我的 MapView 是 mapa;

              @Override
          public boolean onTouchEvent(MotionEvent event, MapView mapView) {
      
              final int action=event.getAction();
              final int x=(int)event.getX();
              final int y=(int)event.getY();
              boolean result=false;
      
                    if (action==MotionEvent.ACTION_DOWN) {
                      for (OverlayItem item : mOverlays) {
                        Point p=new Point(0,0);
      
                        mapa.getProjection().toPixels(item.getPoint(), p);
      
                            //I maintain the hitTest's bounds so you can still
                            //press near the marker
                        if (hitTest(item, marker, x-p.x, y-p.y)) {
                          result=true;
      
                          inDrag=item;
      
                          mOverlays.remove(inDrag);
                          populate();
      
                              //Instead of using the DragImageOffSet and DragTouchOffSet
                              //I use the x and y coordenates from the Point
                          setDragImagePosition(x, y);
      
                          dragImage.setVisibility(View.VISIBLE);
      
                          break;
                        }
                      }
                    }
                    else if (action==MotionEvent.ACTION_MOVE && inDrag!=null) {
                      setDragImagePosition(x, y);
      
                      result=true;
                    }
                    else if (action==MotionEvent.ACTION_UP && inDrag!=null) {
                      dragImage.setVisibility(View.GONE);
      
                          //I get the geopoint without using any OffSet, directly with the 
                          //Point coordenates
                      GeoPoint pt=mapa.getProjection().fromPixels(x,y);
      
                      OverlayItem toDrop=new OverlayItem(pt, inDrag.getTitle(),
                                                         inDrag.getSnippet());
                      orig = inDrag.getMarker(0);
      
                          //In my case I had down heading Arrows as markers, so I wanted my 
                          //bounds to be at the center bottom
                      toDrop.setMarker(boundCenterBottom(orig));
      
                      mOverlays.add(toDrop);
                      populate();
      
                      inDrag=null;
                      result=true;
                    }
      
      
                 return(result || super.onTouchEvent(event, mapView));
      
      
          }
      
          private void setDragImagePosition(int x, int y) {
            RelativeLayout.LayoutParams lp=
              (RelativeLayout.LayoutParams)dragImage.getLayoutParams();
      
                //Instead of using OffSet I use the Point coordenates.
                //I want my arrow to appear pointing to the point I am moving, so 
                //I set the margins as the Point coordenates minus the Height and half the
                //width of my arrow.
            lp.setMargins(x-(dragImage.getWidth()/2),y-dragImage.getHeight(), 0, 0);
            dragImage.setLayoutParams(lp);
          }
      

      这样,您的箭头就会出现在您按下的位置,而不是箭头从原来的位置移动。

      【讨论】:

        【解决方案6】:

        Here是Android Mapview中Drag And Drop pin的完整代码

        【讨论】:

        • @danielgomezrico:你好,你在地图中得到拖放了吗?
        • @Ashok D 源代码和文章的链接已损坏。
        • @ashok 这是一个损坏的链接
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多