Creating OnDragListener for Google Map v2 Fragment

draggable marker google maps android
google maps android api v2
move marker google maps android
android mapview
default marker in google map
android kotlin google map
google maps sdk android marker
get marker from google map android

I’m trying to setup an onDrag Listener for a google map fragment, but can’t get the drag event to fire. Since the map doesn't support drag events directly, I'm trying to implement a drag listener for the View. I know about the onMarkerDrag event, but that does me no good since I'm not trying to move markers around.

The reason for trapping map drag events is twofold:

First to detect if the user has panned the map. If they haven't, I like to keep their location on the screen, and animate to their location if it's not on the map. If they have panned the map, I assume they know what they want to see and force the location on the screen. (this seems like something that should be included in the API)

The second reason for trapping is to allow users to draw lines and polygons on the map. I can do this with onTap events(adding points), but I'd like to be able to let them freehand it as well.

My code looks like this:

mainActivity:

    mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
    setUpMapIfNeeded();
    mMapView = findViewById(R.id.map);
    myMapDragListener = new MapDragListener();
    mMapView.setOnDragListener(myMapDragListener);

The Listener:

public class MapDragListener implements OnDragListener {
    /**
     * 
     */
    public MapDragListener() {
        super();
        say.logCat("MapDragListener: I'm ALIVE!!!!");
    }

    private AkamaiAnnounce say = new AkamaiAnnounce();
    private boolean inDrag;
    private boolean hasPanned=false;

    @Override
    public boolean onDrag(View v, DragEvent event) {
        say.logCat("MapDragListener.onDrag: " + event.toString());
        //String dotTAG = (String) getTag();
        if (event.getLocalState() != this) {
          return false;
        }
        boolean myResult = true;
        int action = event.getAction();
        float x = event.getX();
        float y = event.getY();
        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
          inDrag = true;
          break;
        case DragEvent.ACTION_DRAG_LOCATION:
          break;
        case DragEvent.ACTION_DRAG_ENTERED:
          break;
        case DragEvent.ACTION_DRAG_EXITED:
          break;
        case DragEvent.ACTION_DROP:
          myResult = false;
          break;
        case DragEvent.ACTION_DRAG_ENDED:
          inDrag = false; // change color of original dot back
          hasPanned=true;
          break;
        default:
          myResult = false;
          break;
        }
        return false;
        //return myResult;

    }

    public boolean hasPanned() {
        return hasPanned;
    }

    public void setHasPanned(boolean hasPanned) {
        this.hasPanned = hasPanned;
    }

}

The map works fine. The listener instantiates, but my onDrag event never fires. Any ideas?

1) Create wrapper class:

public class MapWrapperLayout extends FrameLayout {

    public interface OnDragListener {
        public void onDrag(MotionEvent motionEvent);
    }

    private OnDragListener mOnDragListener;

    public MapWrapperLayout(Context context) {
        super(context);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mOnDragListener != null) {
            mOnDragListener.onDrag(ev);
        }
        return super.dispatchTouchEvent(ev);
    }

    public void setOnDragListener(OnDragListener mOnDragListener) {
        this.mOnDragListener = mOnDragListener;
    }
}

2) Create subclass of MapFragment class:

public class CustomMapFragment extends SupportMapFragment {

    private View mOriginalView;
    private MapWrapperLayout mMapWrapperLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mOriginalView = super.onCreateView(inflater, container, savedInstanceState);

        mMapWrapperLayout = new MapWrapperLayout(getActivity());
        mMapWrapperLayout.addView(mOriginalView);

        return mMapWrapperLayout;
}

    @Override
    public View getView() {
        return mOriginalView;
    }

    public void setOnDragListener(MapWrapperLayout.OnDragListener onDragListener) {
        mMapWrapperLayout.setOnDragListener(onDragListener);
    }

3.1) Finally, in your activity:

    // Google map init block
    CustomMapFragment customMapFragment = ((CustomMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
    customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {
        @Override
        public void onDrag(MotionEvent motionEvent) {
            Log.d("ON_DRAG", String.format("ME: %s", motionEvent));
            // Handle motion event:
        }
    });
    GoogleMap map = customMapFragment.getMap();

3.2) ... and in your layout:

<fragment android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:name="your.package.CustomMapFragment"/>

android, 1) Create wrapper class: public class MapWrapperLayout extends FrameLayout { public interface OnDragListener { public void onDrag(MotionEvent  I’m trying to setup an onDrag Listener for a google map fragment, but can’t get the drag event to fire. Since the map doesn't support drag events directly, I'm trying to implement a drag listener for the View. I know about the onMarkerDrag event, but that does me no good since I'm not trying to move markers around.

To get drag event listener a fragment containing googleMap, one can use below method of google. We can get the target position of map.

googleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
          @Override
          public void onCameraIdle() {   
              Log.e(TAG,"==camera idle=="+ googleMap.getCameraPosition().target);

          }
      });
googleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
        @Override
        public void onCameraMoveStarted(int reason) {
            if (reason ==REASON_GESTURE) {
                isMaptouched=true;
                Toast.makeText(getActivity(), "The user gestured on the map.",
                        Toast.LENGTH_SHORT).show();
            } else if (reason ==REASON_API_ANIMATION) {
                Toast.makeText(getActivity(), "The user tapped something on the map.",
                        Toast.LENGTH_SHORT).show();
            } else if (reason ==REASON_DEVELOPER_ANIMATION) {
                Toast.makeText(getActivity(), "The app moved the camera.",
                        Toast.LENGTH_SHORT).show();
            }
        }


    });

android Creating OnDragListener for Google Map v2 Fragment , android Creating OnDragListener for Google Map v2 Fragment? googleMap.​setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() { @Override​  Créer OnDragListener pour Google Map V2 Fragment j'essaie de configurer un écouteur onDrag pour un fragment de carte google, mais je ne peux pas faire démarrer l'événement drag. Puisque la carte ne supporte pas les drag events directement, j'essaye d'implémenter un écouteur de drag pour la vue.

I solved it using the onCameraMoveCancelledListener:

 mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {
            stopCamera=true;
        }
    });


    mMap.setOnCameraMoveCanceledListener(new GoogleMap.OnCameraMoveCanceledListener() {
        @Override
        public void onCameraMoveCanceled() {
            stopCamera = true;
        }
    });

Map Objects | Maps SDK for Android, xml: Adding a SupportMapFragment in a layout definition. Add a map to an Android app. See the getting started guide for a quick way to create an app using the  Creates a map fragment. This constructor is public only for use by an inflater. Use newInstance() to create a MapFragment programmatically.

I did something like similar using a BehaviorSubject to tell if the map was dirty (moved by user)

    storeMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
        @Override
        public void onCameraMoveStarted(int reason) {
            if (reason == REASON_GESTURE) {
                mapIsDirty.onNext(true);
            }
        }
    });
    storeMap.setOnCameraIdleListener(new OnCameraIdleListener() {
        @Override
        public void onCameraIdle() {
            if(mapIsDirty.getValue()) {
            // Do happy things
            mapIsDirty.onNext(false);
            }
        }
    });

MapView | Google APIs for Android, For more information, read the Google Maps SDK for Android developer guide. You must call this method from the parent Activity/Fragment's  This video is on implementing a basic google map in fragments. Do Like, Comment and share. How to implement Google Map in fragment | Android Studio How to create a custom Google Map with

How to draw free hand polygon in Google map V2 in Android?, Creating OnDragListener for Google Map v2 Fragment Also check this one .. How to draw a shape on the map fragment by touching it using google map V2  onAttach()The fragment instance is associated with an activity instance.The fragment and the activity is not fully initialized. Typically you get in this method a reference to the activity which uses the fragment for further initialization work. onCreate() The system calls this method when creating the fragment. You should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.

Android - Using drag and drop in your application, This tutorial describes how to use drag and drop in Android. A view with OnDragListener which are used as a drop zone, gets a OnDragListener assigned via the setOnDragListener . In this part you create several XML drawables in the res/drawable folder. Android Location API and Google Maps. I want to draw a Free Hand Polygon on the Map in Google Map V2. This task was possible with Overlay Map V1 but Google Map has removed that class from V2. (Per this Google Map V2 has Remove Overlay Class). Good Example for Google Map V1 to draw free style polygon.

Android Studio Essentials, L. layout new layout, creating 43,44 LogCat 83, 84 Login activity 18 low-density dots per inch (ldpi) 48 fragment about 75 URL 16 Fullscreen Activity 17. G. Google Cloud Messaging (GCM) 77,78 Google Maps Activity 17 Google Maps 51 OnCreateContextMenu event 51 OnDragListener event 51 OnFocusChange [​107] Copy the URL from google_map_api.xml file to generate Google map key. Paste the copied URL at the browser. It will open the following page. Click on Create API key to generate API key. After clicking on Create API key, it will generate our API key displaying the following screen. Copy this generated API key in our google_map_api.xml file. activity_maps.xml

Comments
  • if you are talking about dragging markers, v2 certainly does have drag listeners. use implements OnMarkerDragListener
  • @tyczj It's not about dragging markers, but panning the whole map. Tim: This won't work because map consumes events. Update your question, say what you want to achieve and maybe we can find a solution.
  • Please mind that there are still there are issues like 4636.
  • @Aleh Im following this. I m getting the Log. I want to listen only the move event . how to get this event only
  • @QadirHussain If I understand your question exactly, then: if(motionEvent.getAction()==MotionEvent.ACTION_MOVE){...}
  • looking for this from last few days.. :)
  • Thanks, was looking for this. Just a note, used OnCameraMoveStartedListener.* to access values of REASON_API_ANIMATION, REASON_DEVELOPER_ANIMATION and REASON_GESTURE
  • I prefer this answer, clean and no extra hack arounds