2017-04-10 5 views
1

Ich erstelle eine Anwendung mit Google Maps v2. Jedesmal, wenn ich nehmen oder ein Bild auswählen, erstelle ich einen benutzerdefinierten Marker und fügen Sie die Karte wie folgt aus:OnMarkerDragStart ändert die Originalposition der Markierung

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == RESULT_OK) { 
     if (requestCode == SELECT_PICTURE_INTENT) { 
      Bitmap photo = createBitmap(data); 
      Marker m = map.addMarker(photoMarker(lastKnownLatLng, photo)); 
      markersInMap.add(m); 
      Log.d(TAG, "Marker created with " + m.getPosition().toString()); 
     } 
    } 
} 

Dann, wenn ich den Marker löschen will, muss ich es zu einem Papierkorb-Symbol ziehen. Wenn der Marker das Mülleimersymbol berührt, entfernt er sich selbst von der Karte. das funktioniert gut. Wenn der Marker den Papierkorb nicht berührt, sollte er an seine ursprüngliche Position zurückkehren, aber das schlägt fehl. Wenn ich anfange, den Marker zu ziehen, sieht es so aus, als würde sich die Position ändern und es endet leicht über der Karte.

@Override 
public void onMarkerDragStart(Marker marker) { 
    trashImageView.setVisibility(View.VISIBLE); 
    draggedMarkerOriginalPosition = marker.getPosition(); 
    Log.d(TAG, "OnMarkerDragStart with " + draggedMarkerOriginalPosition.toString()); 
} 

Diese beiden Methoden Dump die NEX Informationen in der logcat, es ist so klar, dass die Markerposition ändert sich, wenn ich Ziehen beginnen, aber ich weiß nicht, warum und wirklich brauchen, dies zu verhindern:

Marker created with lat/lng: (19.3457139,-99.1522399) 
OnMarkerDragStart with lat/lng: (19.35094919370183,-99.15169514715672) 

das ist mein ganzer Aktivitätscode:

public class MapsActivity extends FragmentActivity implements 
     OnMapReadyCallback, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     com.google.android.gms.location.LocationListener, 
     GoogleMap.OnMarkerDragListener { 

    private static final String TAG = "MAP_ACTIVITY"; 
    private static final int SELECT_PICTURE_INTENT = 1; 

    private GoogleMap map; 
    private Polyline gpsTrack; 
    private SupportMapFragment mapFragment; 
    private GoogleApiClient googleApiClient; 
    private Uri imageUri; 
    private LatLng lastKnownLatLng; 
    private List<Marker> markersInMap = new ArrayList<>(); 
    private ImageView trashImageView; 
    private LatLng draggedMarkerOriginalPosition; 

    private enum MapStatus { 
     EXPANDED, NORMAL, MINIMIZED 
    } 

    private MapStatus mapStatus = MapStatus.NORMAL; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_maps); 

     mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 

     moveMapLocationButton(); 

     ImageButton down = (ImageButton) findViewById(R.id.down_arrow); 
     down.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       animateDownMapView(); 
      } 
     }); 

     ImageButton up = (ImageButton) findViewById(R.id.up_arrow); 
     up.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       animateUpMapView(); 
      } 
     }); 

     ImageView camara = (ImageView) findViewById(R.id.camara); 
     camara.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       startImageChoosingIntent(); 
      } 
     }); 

     Button finalizar = (Button) findViewById(R.id.btn_finalizar_recorrido); 
     finalizar.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       gpsTrack.setPoints(new ArrayList<LatLng>()); 
       for(Marker m : markersInMap) m.remove(); 
       markersInMap.clear(); 
      } 
     }); 


     if (googleApiClient == null) { 
      googleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 

     trashImageView = (ImageView) findViewById(R.id.trash); 

    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     map = googleMap; 

     map.addTileOverlay(new TileOverlayOptions().tileProvider(new CustomMapTileProvider(getResources().getAssets()))); 

     LatLng calymayor = new LatLng(19.345822, -99.152274); 
     map.moveCamera(CameraUpdateFactory.newLatLng(calymayor)); 
     map.moveCamera(CameraUpdateFactory.newLatLngZoom(calymayor, 15)); 

     PolylineOptions polylineOptions = new PolylineOptions(); 
     polylineOptions.color(Color.CYAN); 
     polylineOptions.width(4); 
     gpsTrack = map.addPolyline(polylineOptions); 

     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     map.setMyLocationEnabled(true); 

     map.setOnMarkerDragListener(this); 

    } 


    private void moveMapLocationButton() { 
     View locationButton = ((View) mapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2")); 
     RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams(); 
     rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); 
     rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); 
     rlp.setMargins(0, 0, 30, 30); 
    } 


    private void animateDownMapView() { 
     ResizeAnimation a = new ResizeAnimation(mapFragment.getView()); 
     a.setDuration(250); 

     if (mapStatus == MapStatus.NORMAL) { 
      mapStatus = MapStatus.EXPANDED; 
      a.setParams(mapFragment.getView().getLayoutParams().height, dpToPx(getResources(), pxToDp(getResources().getDisplayMetrics().heightPixels))); 
      mapFragment.getView().startAnimation(a); 
     } else if (mapStatus == MapStatus.MINIMIZED) { 
      mapStatus = MapStatus.NORMAL; 
      mapFragment.getView().setLayoutParams(
        new LinearLayout.LayoutParams(
          LinearLayout.LayoutParams.MATCH_PARENT, 
          0, 
          0.3333f 
        ) 
      ); 
     } 
    } 

    private void animateUpMapView() { 
     if (mapStatus == MapStatus.NORMAL) { 
      mapStatus = MapStatus.MINIMIZED; 
      mapFragment.getView().setLayoutParams(
        new LinearLayout.LayoutParams(
          LinearLayout.LayoutParams.MATCH_PARENT, 
          0, 
          0.04f 
        ) 
      ); 
     } else if (mapStatus == MapStatus.EXPANDED) { 
      mapStatus = MapStatus.NORMAL; 
      mapFragment.getView().setLayoutParams(
        new LinearLayout.LayoutParams(
          LinearLayout.LayoutParams.MATCH_PARENT, 
          0, 
          0.3333f 
        ) 
      ); 
     } 
    } 

    private int pxToDp(int px) { 
     DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); 
     int dp = Math.round(px/(displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT)); 
     return dp; 
    } 

    private int dpToPx(Resources res, int dp) { 
     return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); 
    } 

    @Override 
    protected void onStart() { 
     googleApiClient.connect(); 
     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     googleApiClient.disconnect(); 
     super.onStop(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     stopLocationUpdates(); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (googleApiClient.isConnected()) { 
      startLocationUpdates(); 
     } 
    } 

    @Override 
    public void onConnected(@Nullable Bundle bundle) { 
     startLocationUpdates(); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

    } 

    @Override 
    public void onLocationChanged(Location location) { 
     lastKnownLatLng = new LatLng(location.getLatitude(), location.getLongitude()); 
     updateTrack(); 
    } 

    protected void startLocationUpdates() { 
     LocationRequest locationRequest = new LocationRequest(); 
     locationRequest.setInterval(5000); 
     locationRequest.setFastestInterval(1000); 
     locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 

     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this); 
    } 

    protected void stopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       googleApiClient, this); 
    } 

    private void startImageChoosingIntent() { 
     Intent pickIntent = new Intent(); 
     pickIntent.setType("image/*"); 
     pickIntent.setAction(Intent.ACTION_GET_CONTENT); 

     Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     String pickTitle = "Seleccionar"; 

     ContentValues values = new ContentValues(); 
     values.put(MediaStore.Images.Media.TITLE, "New Picture"); 
     values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera"); 
     imageUri = getContentResolver().insert(
       MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
     takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 

     Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle); 
     chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent}); 

     startActivityForResult(chooserIntent, SELECT_PICTURE_INTENT); 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (resultCode == RESULT_OK) { 
      if (requestCode == SELECT_PICTURE_INTENT) { 
       Bitmap photo = createBitmap(data); 
       Marker m = map.addMarker(photoMarker(lastKnownLatLng, photo)); 
       markersInMap.add(m); 
       Log.d(TAG, "Marker created with " + m.getPosition().toString()); 
      } 
     } 
    } 

    private Bitmap createBitmap(Intent data) { 
     boolean isCamera; 
     Bitmap photoTaken = null; 

     if(data == null) { 
      isCamera = true; 
     } else { 
      String action = data.getAction(); 
      if(action == null) { 
       isCamera = false; 
      } else { 
       isCamera = action.equals(MediaStore.ACTION_IMAGE_CAPTURE); 
      } 
     } 
     if(!isCamera) { 
      imageUri = data.getData(); 
     } 

     try { 
      photoTaken = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return photoTaken; 
    } 

    private MarkerOptions photoMarker(LatLng latlng, Bitmap bitmap) { 
     return new MarkerOptions() 
       .position(latlng) 
       .draggable(true) 
       .icon(BitmapDescriptorFactory.fromBitmap(Utils.getMarkerBitmap(getBaseContext(), bitmap))); 
    } 

    private void updateTrack() { 
     List<LatLng> points = gpsTrack.getPoints(); 
     points.add(lastKnownLatLng); 
     gpsTrack.setPoints(points); 
    } 

    @Override 
    public void onMarkerDragStart(Marker marker) { 
     trashImageView.setVisibility(View.VISIBLE); 
     draggedMarkerOriginalPosition = marker.getPosition(); 
     Log.d(TAG, "OnMarkerDragStart with " + draggedMarkerOriginalPosition.toString()); 
    } 

    @Override 
    public void onMarkerDrag(Marker marker) { 
     Point markerScreenPosition = map.getProjection().toScreenLocation(marker.getPosition()); 
     int size = 0; 
     if (overlap(markerScreenPosition, trashImageView)) { 
      size = dpToPx(getResources(), 60); 
     } else { 
      size = dpToPx(getResources(), 40); 
     } 
     FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size, size); 
     params.gravity = Gravity.BOTTOM | Gravity.RIGHT; 
     trashImageView.setLayoutParams(params); 
    } 

    @Override 
    public void onMarkerDragEnd(Marker marker) { 
     trashImageView.setVisibility(View.GONE); 
     Point markerScreenPosition = map.getProjection().toScreenLocation(marker.getPosition()); 
     if (overlap(markerScreenPosition, trashImageView)) { 
      marker.remove(); 
     } else { 
      marker.setPosition(draggedMarkerOriginalPosition); 
      Log.d(TAG, "OnMarkerDragEnd with " + draggedMarkerOriginalPosition.toString()); 
     } 
    } 

    private boolean overlap(Point point, ImageView imgview) { 
     int[] imgCoords = new int[2]; 
     imgview.getLocationOnScreen(imgCoords); 
     boolean overlapX = point.x < imgCoords[0] + imgview.getWidth() && point.x > imgCoords[0] - imgview.getWidth(); 
     boolean overlapY = point.y < imgCoords[1] + imgview.getHeight() && point.y > imgCoords[1] - imgview.getWidth(); 
     return overlapX && overlapY; 
    } 

} 

und diese Bilder zeigen, wo die Markierung beginnt und wo es endet, nachdem ich ziehen und lassen sie die Markierung irgendwo außerhalb des tra sh kann.

enter image description here

enter image description here

Antwort

1

OK, so kam ich mit dieser Lösung auf. Ich bin mir nicht sicher, ob es das Beste ist, aber es funktioniert.

I geändert:

private List<Marker> markersInMap = new ArrayList<>(); 

An:

private Map<Marker, LatLng> markersInMap = new HashMap<>(); 

Dann, wenn ich den Marker hinzufügen:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == RESULT_OK) { 
     if (requestCode == SELECT_PICTURE_INTENT) { 
      Bitmap photo = createBitmap(data); 
      Marker m = map.addMarker(photoMarker(lastKnownLatLng, photo)); 
      markersInMap.put(m, new LatLng(lastKnownLatLng.latitude, lastKnownLatLng.longitude)); 
      Log.d(TAG, "Marker created with " + m.getPosition().toString()); 
     } 
    } 
} 

Und schließlich, es zu setzen zurück in seine ursprüngliche Position:

@Override 
public void onMarkerDragEnd(Marker marker) { 
    trashImageView.setVisibility(View.GONE); 
    Point markerScreenPosition = map.getProjection().toScreenLocation(marker.getPosition()); 
    if (overlap(markerScreenPosition, trashImageView)) { 
     marker.remove(); 
     Log.d(TAG, "OnMarkerDragEnd " + "removed"); 
    } else { 
     marker.setPosition(markersInMap.get(marker)); 
     Log.d(TAG, "OnMarkerDragEnd " + marker.getPosition().toString()); 
    } 
} 
+0

Diese Problemumgehung ist die einzige Lösung, die ich für das gleiche Problem gefunden habe. Könnten Sie Ihre Antwort als akzeptiert markieren, damit sie anderen helfen kann? – antonio

Verwandte Themen