How does one implement drag and drop for Android marker?
Asked Answered
S

6

30

Hi? I am working on a MapView app in Android. I have three markers that I want to be able to use the Google Map API getlocation-function on, later on. In order to try it out I would like to move the marker with a drag and drop-function, and then check the location.

Anyone who has gotten a drag and drop to work on an android marker, or know a way to start figuring it out?

/AK

Selfsacrifice answered 9/10, 2010 at 18:45 Comment(0)
K
25

Here is a sample project from one of my books showing drag-and-drop movement of markers on a Google Map in Android.

In a nutshell, it uses onTouchEvent() to detect when the user touches and holds their finger near a marker. It then removes the marker from the overlay, but puts the same image over top of the map using RelativeLayout. Then, on "move" touch events, the image is moved (faster than forcing the whole overlay to redraw). When the finger is lifted, the image is removed, but the marker is put back in the overlay at the new spot.

Katy answered 9/10, 2010 at 19:50 Comment(3)
Thanks a lot for the link and explanation! I am new to Android, so it is good for me to look at the structure of a well working project, to get the idea of how to get things done for real and not just throw things in there. Thank you.Selfsacrifice
I think this outdated ans now. bcoz v2 dosenot support overlay.Do u have something for V2 alsoAdobe
@ShakeebAyaz: See UrMi's answer for the approach for Maps V2. This answer is for Maps V1, the original Android map solution.Katy
K
55

Implement Google Maps Android API v2, refer this: https://developers.google.com/maps/documentation/android/ and set on GoogleMap object setOnMarkerDragListener. For Ex:

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));
Kirstiekirstin answered 11/11, 2013 at 10:1 Comment(3)
any way to enable drag of marker on tap instead of long press ?Silversmith
No. Because on tap it will perform onMarkerClick for the marker's info window to open and it is default behavior so we can't modify this event.Kirstiekirstin
Thanks for draggable(true)! Didn't find mistake, until you hinted.Threesome
K
25

Here is a sample project from one of my books showing drag-and-drop movement of markers on a Google Map in Android.

In a nutshell, it uses onTouchEvent() to detect when the user touches and holds their finger near a marker. It then removes the marker from the overlay, but puts the same image over top of the map using RelativeLayout. Then, on "move" touch events, the image is moved (faster than forcing the whole overlay to redraw). When the finger is lifted, the image is removed, but the marker is put back in the overlay at the new spot.

Katy answered 9/10, 2010 at 19:50 Comment(3)
Thanks a lot for the link and explanation! I am new to Android, so it is good for me to look at the structure of a well working project, to get the idea of how to get things done for real and not just throw things in there. Thank you.Selfsacrifice
I think this outdated ans now. bcoz v2 dosenot support overlay.Do u have something for V2 alsoAdobe
@ShakeebAyaz: See UrMi's answer for the approach for Maps V2. This answer is for Maps V1, the original Android map solution.Katy
E
8

For MapsV2. Use the google map events. Don't write your own.

        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) {
            }
        });
Exstipulate answered 31/7, 2016 at 11:20 Comment(1)
You didn't write about draggable(true) for marker.Threesome
P
4

Below is the answer to Kotlin Lover! It's quite very simple! As you can see below.

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

Below is the liner code for getting the end dragging location

   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)
        }
    })
Portecochere answered 11/5, 2020 at 7:30 Comment(0)
W
2

I found a little optimization for the CommonsWare drag and drop's brilliant function.

I was doing some precise meashurements with markers on my map, and I wanted my marker to be exactly on the spot I touched and lifted my finger so the meashurment was exactly precise.

On the original from CommonsWare if you touch "near" the marker, the marker does not go to that exact point, but moves along with your finger's movement. I needed the marker to appear just below my finger on the ACTION_DOWN, ACTION_MOVE and ACTION_UP.

Here is the code if someone need's it. I have to thank CommonsWare to make this function, it's a really good idea.

This is the part of the code I modified.

My MapView is 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);
    }

With this you get your arrow appearing where you press with your, instead of the arrow moving from where it was.

Wernher answered 24/5, 2012 at 18:3 Comment(0)
S
-2

Here is Complete code of Drag And Drop pin in Mapview in Android

Secrete answered 24/7, 2012 at 10:45 Comment(3)
@danielgomezrico : Hi, did you get the drag and drop in map?Asteroid
@Ashok D Link broken for the source code and article.Probation
@ashok it was a broken linkMacready

© 2022 - 2024 — McMap. All rights reserved.