2013-06-20 12 views
8

Sto provando a impostare un Listener onDrag per un frammento di mappa di google, ma non riesco a far scattare l'evento di trascinamento. Poiché la mappa non supporta direttamente gli eventi di trascinamento, sto cercando di implementare un listener di trascinamento per la vista. Conosco l'evento onMarkerDrag, ma questo non mi fa bene visto che non sto cercando di spostare i marcatori.Creazione di OnDragListener per Google Map v2 Frammento

La ragione per la cattura di eventi mappa di trascinamento è duplice:

primo a rilevare se l'utente ha stroncato la mappa. In caso contrario, mi piace mantenere la loro posizione sullo schermo e animare la loro posizione se non è sulla mappa. Se hanno filtrato la mappa, presumo che sappiano cosa vogliono vedere e forzare la posizione sullo schermo. (questo sembra qualcosa che dovrebbe essere incluso nell'API)

Il secondo motivo per il trapping è consentire agli utenti di disegnare linee e poligoni sulla mappa. Posso farlo con gli eventi onTap (aggiungendo punti), ma mi piacerebbe essere in grado di lasciarli anche a mano libera.

Il mio codice è simile al seguente:

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; 
    } 

} 

La mappa funziona bene. L'ascoltatore crea un'istanza, ma il mio evento onDrag non si attiva mai. Qualche idea?

+0

se si parla di marcatori trascinando, V2 certamente ha ascoltatori di trascinamento. usa 'implementa OnMarkerDragListener' – tyczj

+1

@tyczj Non si tratta di trascinare i marcatori, ma di esplorare l'intera mappa. Tim: non funzionerà perché la mappa consuma eventi. Aggiorna la tua domanda, dì ciò che vuoi raggiungere e forse possiamo trovare una soluzione. –

risposta

18

1) Creare classe wrapper:

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) Creare sottoclasse di MapFragment:

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) Infine, nella vostra attività:

// 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). .. e nel layout:

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

Ricorda che ci sono ancora problemi come [4636] (https://code.google.com/p/gmaps-api-issues/issues/detail?id=4636). – JJD

+0

@Aleh Sto seguendo questo. Sto ricevendo il registro. Voglio ascoltare solo l'evento di spostamento. come ottenere questo evento solo –

+1

@QadirHussain Se ho compreso esattamente la tua domanda, allora: if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {...} – Aleh

4

Per ottenere il listener di eventi di trascinamento un frammento contenente googleMap, è possibile utilizzare il metodo di seguito di google. Possiamo ottenere la posizione di destinazione della mappa.

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(); 
      } 
     } 


    }); 
+1

cercando questo da ultimi giorni .. :) –

0

ho fatto qualcosa di simile simile usando un BehaviorSubject per dire se la mappa era sporco (spostato dall'utente)

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); 
      } 
     } 
    }); 
Problemi correlati