Android Question MarkerDragListener in GoogleMapExtras

Discussion in 'Android Questions' started by Roger Daley, May 13, 2015.

Similar threads

B4A Question Google Map Marker icon Chopped
B4A Library GoogleMapsExtras
B4A Question Create HueColor
B4A Tutorial Google Maps
B4A Question Google Map Rotate Marker
  1. Roger Daley

    Roger Daley Well-Known Member Licensed User

    Hi All,

    I am trying to get the correct process for MarkerDragListener operation when there are multiple markers.

    In the code below there are two markers and originally I "Dimensioned" a DragListener for each marker with a corresponding Sub for each marker-drag. I found that only one sub was called, and called when either marker was dragged.

    1. Is this correct or have I missed something?
    2. If correct how do I differentiate the markers for different Subs or different actions within the Sub.

    Code:
    Sub Map_Ready
      
    Log("map ready")
      gmap = mFragment.GetMap
      
    If gmap.IsInitialized = False Then
      
    ToastMessageShow("Error initializing map."True)
      
    Else
      
    'Create BTSMarker Options including ICON
         Dim BTSOptions As MarkerOptions
         
    Dim BitmapDescriptor1 As BitmapDescriptor
         
    Dim BitmapDescriptorFactory1 As BitmapDescriptorFactory
      BTSOptions.Initialize
      BTSOptions.Draggable(
    True
      BTSOptions.Position2(BTSLat, BTSLng).Snippet(
    "pkt").Title("BASE")
         BitmapDescriptor1=BitmapDescriptorFactory1.FromAsset(
    "bts.png"
         BTSOptions.Icon(BitmapDescriptor1)
         
    'Creat BTS marker and "Drag" listener
         BTSMarker=GoogleMapsExtras1.AddMarker(gmap, BTSOptions)
      
    Dim BTSDragListener As OnMarkerDragListener
      BTSDragListener.Initialize(
    "BTSDragListener")
      GoogleMapsExtras1.SetOnMarkerDragListener(gmap,BTSDragListener)

      
    'Create LANDMarker Options including ICON
         Dim LANDOptions As MarkerOptions
         
    Dim BitmapDescriptor2 As BitmapDescriptor
         
    Dim BitmapDescriptorFactory2 As BitmapDescriptorFactory
      LANDOptions.Initialize
      LANDOptions.Draggable(
    True
      LANDOptions.Position2(LANDLat, LANDLng).Snippet(
    "pkt").Title("LANDMARK")
         BitmapDescriptor2=BitmapDescriptorFactory2.FromAsset(
    "landmark.png"
         LANDOptions.Icon(BitmapDescriptor2)
         
    'Creat LANDMarker marker and "Drag" listener
         LANDMarker =GoogleMapsExtras1.AddMarker(gmap, LANDOptions)
      
    'Dim LANDDragListener As OnMarkerDragListener
      'LANDDragListener.Initialize("LANDDragListener")
      'GoogleMapsExtras1.SetOnMarkerDragListener(gmap,LANDDragListener)

      cp.Initialize2(MapLat, MapLng, MapZoom, MapBearing, 
    0 )
      gmap.AnimateCamera(cp)
         gmap.maptype = MapTypeInt
           
    'MapTypeInt: 1=Road Map, 2=Satellite, 3=Terrain, 4=Satellite with Labels
         gmap.GetUiSettings.CompassEnabled = False
      
    End If
    End Sub

    Sub BTSDragListener_DragEnd(Marker1 As Marker)
      
    'Log("DragEnd")
        Dim BTSLatLng As LatLng
        BTSLatLng = BTSMarker.Position
        BTSLat = BTSLatLng.Latitude
        BTSLng = BTSLatLng.Longitude
    End Sub
    Regards Roger
     
  2. DonManfred

    DonManfred Expert Licensed User

    One time Marker1 is the BTSMarker the other time Marker1 is the LANDMarker.
    If you can set a TAG when creating the markers (dont know) you can use this tag to differentiate them
     
  3. warwound

    warwound Expert Licensed User

    In theory you can create a drag listener for each marker and when each marker is dragged only it's drag listener will raise events.
    Both drag listeners should not raise events when a single marker is dragged.

    Again in theory you could use a single drag listener to listen for drag events on both markers.
    Then in the various drag listener _Drag??? event subs you'd need a way to identify which marker the event relates to.

    I say 'in theory' as you may have found a bug in GoogleMapsExtras.

    Can you put a simple project together that displays 2 draggable markers each with their own drag listener?
    I'll give it a test and see what the problem is.
     
    DonManfred likes this.
  4. DonManfred

    DonManfred Expert Licensed User

    I dont know whether it is already doable (dont use the lib) but if the Marker object can hold a "Tag" then it should be work without changes too.
    The TO just need to use the Marker1.Tag to distinguish the calls in this case.
    Just my 2 cent without working with markers actually
     
  5. warwound

    warwound Expert Licensed User

    Ooops my mistake - ignore what i posted in my last message.
    The GoogleMap can have only a single drag listener set and you have to identify the dragged marker in the drag listener _Drag??? event subs.

    So that means you need a way to identify the dragged marker.

    @DonManfred a marker does have a unique String read only 'id', but it does not have a readable/writable Tag property like standard Views have.
    Here is the documentation for the Marker getId() method:
    https://developer.android.com/reference/com/google/android/gms/maps/model/Marker.html#getId()
    The MarkerExtras object can be used to get this id, alternatively JavaObject could be used.

    But rather than using the id i'd suggest keeping global references to each draggable marker and comparing the marker passed to the drag listener sub to these draggable markers:

    Code:
    '    ** i'll assume you dim BTSMarker and LANDMarker as Global objects **

    Sub Map_Ready
      
    Log("map ready")
      gmap = mFragment.GetMap
      
    If gmap.IsInitialized = False Then
      
    ToastMessageShow("Error initializing map."True)
      
    Else
      
    'Create BTSMarker Options including ICON
         Dim BTSOptions As MarkerOptions
         
    Dim BitmapDescriptor1 As BitmapDescriptor
         
    Dim BitmapDescriptorFactory1 As BitmapDescriptorFactory
      BTSOptions.Initialize
      BTSOptions.Draggable(
    True
      BTSOptions.Position2(BTSLat, BTSLng).Snippet(
    "pkt").Title("BASE")
         BitmapDescriptor1=BitmapDescriptorFactory1.FromAsset(
    "bts.png"
         BTSOptions.Icon(BitmapDescriptor1)
         
    'Creat BTS marker
         BTSMarker=GoogleMapsExtras1.AddMarker(gmap, BTSOptions)

      
    'Create LANDMarker Options including ICON
         Dim LANDOptions As MarkerOptions
         
    Dim BitmapDescriptor2 As BitmapDescriptor
         
    Dim BitmapDescriptorFactory2 As BitmapDescriptorFactory
      LANDOptions.Initialize
      LANDOptions.Draggable(
    True
      LANDOptions.Position2(LANDLat, LANDLng).Snippet(
    "pkt").Title("LANDMARK")
         BitmapDescriptor2=BitmapDescriptorFactory2.FromAsset(
    "landmark.png"
         LANDOptions.Icon(BitmapDescriptor2)
         
    'Creat LANDMarker marker
         LANDMarker =GoogleMapsExtras1.AddMarker(gmap, LANDOptions)

      
    ' create DragListener
      Dim DragListener1 As OnMarkerDragListener
      DragListener1.Initialize(
    "DragListener1")
      GoogleMapsExtras1.SetOnMarkerDragListener(gmap,DragListener1)
      
      cp.Initialize2(MapLat, MapLng, MapZoom, MapBearing, 
    0 )
      gmap.AnimateCamera(cp)
         gmap.maptype = MapTypeInt
           
    'MapTypeInt: 1=Road Map, 2=Satellite, 3=Terrain, 4=Satellite with Labels
         gmap.GetUiSettings.CompassEnabled = False
      
    End If
    End Sub

    Sub DragListener1_DragEnd(Marker1 As Marker)
      
    'Log("DragEnd")
      Select Marker1
          
    Case BTSMarker
             
    Dim BTSLatLng As LatLng
            BTSLatLng = BTSMarker.Position
            BTSLat = BTSLatLng.Latitude
          BTSLng = BTSLatLng.Longitude
          
    Case LANDMarker
            
    ' do something when LANDMarker is dragged
      End Select
    End Sub
     
    Roger Daley and DonManfred like this.
  6. Roger Daley

    Roger Daley Well-Known Member Licensed User

    Thanks for the feedback guys

    Warwound your explanation was spot on. As I already keep lat and long of each marker it is easy to check which has moved.
    The important thing is I will be doing it correctly and not just guessing.

    Many thanks Roger
     
  7. DonManfred

    DonManfred Expert Licensed User

    so i guess this should help here... After creating a marker; get the id of it and hold this info. Use this info then to identify the marker used in the raised event
     
    Roger Daley likes this.
  8. Roger Daley

    Roger Daley Well-Known Member Licensed User

    Thanks Donmanfred,
    I now have a couple of options with a clear picture of how markerdraggable works.

    Roger
     
  9. DonManfred

    DonManfred Expert Licensed User

    Share the solution if you are done.... It may be a help for others in future!
     
    eurojam likes this.
  10. Roger Daley

    Roger Daley Well-Known Member Licensed User

    I will post when finished but currently diverted by management.

    Roger
     
  11. warwound

    warwound Expert Licensed User

    That's possible but means you now have 2 global references: a reference to the marker id and a reference to the marker itself.
    My code example shows that if you have a reference to the marker there's no real need to keep a reference to the marker id too.

    Ideally the GoogleMap would have a method such as:

    GetMarkerById(MarkerId As String) As Marker

    But it doesn't - there's requests for Google to implement such a method but currently no such method.

    You could create a Map where the Map keys are marker id values and the Map values are marker objects.
    It depends on how many marker objects you need to reference - whether it's worth creating a Map or simply keeping a handful of direct references:

    Code:
    ' in Globals
    Dim BTSMarker As Marker
    Dim LANDMarker As Marker
    OR

    Code:
    ' in Globals
    Dim MarkersById As Map
     
  12. eurojam

    eurojam Well-Known Member Licensed User

    I usually use a map where the marker is the key and a customtype holds the values, so i have a complete dataset for each marker.
    Code:
    Type POI (id As Long, station As String, teaser As String, lat As Double, lon As Double, audio As Int, video As Int, image As Int, aMarker1 As Marker, aMarker2 As Marker)
    Dim Markers1 As Map
    Dim Markers2 As Map
    in this example I am using two markers. Marker2 is shown after the marker was clicked (an open or closed treasure box for example)

    when a marker event like the drag event is fired, or any other event with marker:
    Code:
    Sub OnInfoWindowClickListener1_click(Marker1 As Marker)
        
    Dim p As POI
       
    If Markers1.Get(Marker1) = Null Then
          p = Markers2.Get(Marker1)
       
    Else
          p = Markers1.Get(Marker1)
       
    End If 
       
    'do something with p
    End Sub
    Hope this helps...o_O
     
  13. Roger Daley

    Roger Daley Well-Known Member Licensed User

    I've tried a few ways and the more I looked, the more Warwounds Select/Case [Post #5] became the best choice for my use. The code I have used is basically Warwounds.
    The other ideas may be preferable for a different project. The info in this thread should be of great help to the next person question dragging markers.

    Regards Roger:)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice