web-dev-qa-db-fra.com

Comment implémenter le glisser-déposer pour le marqueur Android?

Salut? Je travaille sur une application MapView sur Android. J'ai trois marqueurs sur lesquels je veux pouvoir utiliser la fonction getlocation de l'API Google Map plus tard. Afin de l'essayer, je voudrais déplacer le marqueur avec une fonction glisser-déposer, puis vérifier l'emplacement.

Quiconque a obtenu un glisser-déposer pour travailler sur un marqueur Android, ou savez-vous comment commencer à le comprendre?

/ AK

27
kakka47

Voici un exemple de projet de n de mes livres montrant le mouvement de glisser-déposer des marqueurs sur une carte Google dans Android.

En bref, il utilise onTouchEvent() pour détecter quand l'utilisateur touche et tient son doigt près d'un marqueur. Il supprime ensuite le marqueur de la superposition, mais place la même image au-dessus de la carte à l'aide de RelativeLayout. Ensuite, lors des événements tactiles de "déplacement", l'image est déplacée (plus rapidement que de forcer la superposition entière à se redessiner). Lorsque le doigt est levé, l'image est supprimée, mais le marqueur est replacé dans la superposition au nouveau point.

25
CommonsWare

Implémentez Google Maps Android API v2, reportez-vous à ceci: https://developers.google.com/maps/documentation/Android/ et définissez-le sur l'objet GoogleMap setOnMarkerDragListener. 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));
45
UrMi

Pour MapsV2. Utilisez les événements google map. N'écrivez pas le vôtre.

        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) {
            }
        });
4
F.O.O

J'ai trouvé une petite optimisation pour la fonction brillante de glisser-déposer de CommonsWare.

Je faisais des mesures précises avec des marqueurs sur ma carte, et je voulais que mon marqueur soit exactement à l'endroit que j'ai touché et levé mon doigt pour que la mesure soit exactement précise.

Sur l'original de CommonsWare si vous touchez "près" du marqueur, le marqueur ne va pas à ce point exact, mais se déplace avec le mouvement de votre doigt. J'avais besoin que le marqueur apparaisse juste en dessous de mon doigt sur les ACTION_DOWN, ACTION_MOVE et ACTION_UP.

Voici le code si quelqu'un en a besoin. Je dois remercier CommonsWare d'avoir fait cette fonction, c'est une très bonne idée.

C'est la partie du code que j'ai modifiée.

Mon MapView est 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);
    }

Avec cela, votre flèche apparaît à l'endroit où vous appuyez avec votre, au lieu de la flèche se déplaçant d'où elle était.

1
Alex89Spain

Ici est le code complet de la broche Drag And Drop dans Mapview dans Android

0
Ashok Domadiya