Creating OnDragListener for Google Map v2 Snippet

I am trying to configure an onDrag Listener for a google map fragment, but cannot trigger a drag event. Since the map does not support direct drag and drop events, I am trying to implement a drag and drop listener for the view. I know about the onMarkerDrag event, but that doesn't do me any good, since I'm not trying to move markers.

The reason for intercepting card drag events is twofold:

First, to determine if the user has launched a map. If they havenโ€™t, I like to keep their location on the screen and animate their location if it is not on the map. If they launched a map, I assume that they know what they want to see, and force a place on the screen. (this is similar to what should be included in the API)

The second reason for capture is to allow users to draw lines and polygons on the map. I can do this using the onTap events (adding points), but I would also like to let them undo it.

My code is as follows:

mainActivity:

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

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 great. The listener fires, but my onDrag event never fires. Any ideas?

+8
android google-maps google-maps-android-api-2 drag
Jun 20 '13 at 20:27
source share
3 answers

1) Create a 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 a subclass of the 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"/> 
+18
Aug 31 '13 at 14:54
source share

To get a drag event listener for a fragment containing googleMap, you can use the google method below. We can get the target position of the 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(); } } }); 
+4
Jun 26 '17 at 6:50
source share

I did something similar using a BehaviorSubject to determine if the map was dirty (moved by the 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); } } }); 
0
Dec 05 '17 at 21:46 on
source share



All Articles