2015-03-26 22 views
5

Trong ứng dụng của tôi cần hiển thị dấu "bản đồ google" di chuyển trơn tru từ điểm này sang điểm khác. tôi sử dụng phương pháp sau đây để các hình ảnh động:Làm thế nào để sửa trơn tru di chuyển điểm đánh dấu trong google maps v2?

public void animateMarker(final Marker marker, final LatLng toPosition, 
          final boolean hideMarker) { 
    final Handler handler = new Handler(); 
    final long start = SystemClock.uptimeMillis(); 
    Projection proj = mMap.getProjection(); 
    Point startPoint = proj.toScreenLocation(marker.getPosition()); 
    final LatLng startLatLng = proj.fromScreenLocation(startPoint); 
    final long duration = 500; 

    final Interpolator interpolator = new LinearInterpolator(); 

    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      long elapsed = SystemClock.uptimeMillis() - start; 
      float t = interpolator.getInterpolation((float) elapsed 
        /duration); 
      double lng = t * toPosition.longitude + (1 - t) 
        * startLatLng.longitude; 
      double lat = t * toPosition.latitude + (1 - t) 
        * startLatLng.latitude; 
      marker.setPosition(new LatLng(lat, lng)); 

      if (t < 1.0) { 
       // Post again 16ms later. 
       handler.postDelayed(this, 16); 
      } else { 
       if (hideMarker) { 
        marker.setVisible(false); 
       } else { 
        marker.setVisible(true); 
       } 
      } 
     } 
    }); 
} 

Nhưng như một kết quả của việc chỉ đơn giản là tạo ra một dấu hiệu mới đến vị trí mới (mặc dù tuổi không được cắt bỏ):

enter image description here

+0

Tôi nghĩ bạn cần nói cho chế độ xem vẽ lại chính nó sau khi bạn thay đổi một vị trí và trước khi bạn bắt đầu chờ. – kaho

+0

Ý của bạn có phải là điểm đánh dấu xóa và thêm điểm đánh dấu mới có vị trí mới không? – Rexhaif

+0

Theo như tôi hiểu, để tiết kiệm tài nguyên, Android không vẽ màn hình cho đến khi kết thúc vòng lặp của bạn ... vì vậy bạn cần phải thông báo cho hệ thống mà bạn muốn vẽ lại màn hình. Có vẻ như điều này sẽ giúp: http://developer.android.com/reference/android/view/View.html#invalidate(android.graphics.Rect) – kaho

Trả lời

18

tôi sao chép một số mã từ số project được đề cập trong số official video.

Tôi đã cố gắng tạo lại mã này với mã này và seems to be working for me này, vì vậy hy vọng mã của tôi sẽ giúp bạn, thậm chí một chút.

static final LatLng SomePos = new LatLng(37.7796354, -122.4159606); 

    try { 
     if (googleMap == null) { 
      googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 
     } 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
     googleMap.setMyLocationEnabled(true); 
     googleMap.setTrafficEnabled(false); 
     googleMap.setIndoorEnabled(false); 
     googleMap.setBuildingsEnabled(true); 
     googleMap.getUiSettings().setZoomControlsEnabled(true); 
     googleMap.moveCamera(CameraUpdateFactory.newLatLng(SomePos)); 
     googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder() 
       .target(googleMap.getCameraPosition().target) 
       .zoom(17) 
       .bearing(30) 
       .tilt(45) 
       .build())); 

     myMarker = googleMap.addMarker(new MarkerOptions() 
       .position(SomePos) 
       .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher)) 
       .title("Hello world")); 


     googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() 
     { 
      @Override 
      public boolean onMarkerClick(Marker arg0) { 

       final LatLng startPosition = myMarker.getPosition(); 
       final LatLng finalPosition = new LatLng(37.7801569,-122.4148528); 
       final Handler handler = new Handler(); 
       final long start = SystemClock.uptimeMillis(); 
       final Interpolator interpolator = new AccelerateDecelerateInterpolator(); 
       final float durationInMs = 3000; 
       final boolean hideMarker = false; 

       handler.post(new Runnable() { 
        long elapsed; 
        float t; 
        float v; 

        @Override 
        public void run() { 
         // Calculate progress using interpolator 
         elapsed = SystemClock.uptimeMillis() - start; 
         t = elapsed/durationInMs; 
         v = interpolator.getInterpolation(t); 

         LatLng currentPosition = new LatLng(
           startPosition.latitude*(1-t)+finalPosition.latitude*t, 
           startPosition.longitude*(1-t)+finalPosition.longitude*t); 

         myMarker.setPosition(currentPosition); 

         // Repeat till progress is complete. 
         if (t < 1) { 
          // Post again 16ms later. 
          handler.postDelayed(this, 16); 
         } else { 
          if (hideMarker) { 
           myMarker.setVisible(false); 
          } else { 
           myMarker.setVisible(true); 
          } 
         } 
        } 
       }); 

       return true; 

      } 

     }); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
+0

cảm ơn bạn rất nhiều – Rexhaif

3

Tôi biết đây là một câu hỏi cũ nhưng ...

Bạn có thể sử dụng giá trị xen vào cho nhiệm vụ này:

fun changePositionSmoothly(marker:Marker?, newLatLng: LatLng){ 
    if(marker == null){ 
     return; 
    } 
    val animation = ValueAnimator.ofFloat(0f, 100f) 
    var previousStep = 0f 
    val deltaLatitude = newLatLng.latitude - marker.position.latitude 
    val deltaLongitude = newLatLng.longitude - marker.position.longitude 
    animation.setDuration(1500) 
    animation.addUpdateListener { updatedAnimation -> 
     val deltaStep = updatedAnimation.getAnimatedValue() as Float - previousStep 
     previousStep = updatedAnimation.getAnimatedValue() as Float 
     marker.position = LatLng(marker.position.latitude + deltaLatitude * deltaStep * 1/100, marker.position.longitude + deltaStep * deltaLongitude * 1/100) 
    } 
    animation.start() 
} 

Để ngăn chặn sự tích tụ lỗi, ở phần cuối của các hình ảnh động bạn có thể thiết lập vị trí mới, nhưng điều này là đủ cho hầu hết các trường hợp.

Các vấn đề liên quan