2016-02-26 15 views
8

Tôi muốn thay đổi nền của điểm đánh dấu cụm khi nhấp chuột. Tôi làm điều này thông quaDefaultClusterRenderer getMarker() trả lại giá trị rỗng khi thu phóng

@Override 
onClusterClick(Cluster<MyObject> cluster) { 
    Marker marker = renderer.getMarker(cluster); 
    marker.setIcon(....); 
} 

Điều này làm việc tốt cho một trường hợp: Khi tôi phóng to hoặc thu nhỏ và số lượng điểm đánh dấu cụm không thay đổi. Ví dụ, nếu tôi có một cụm 15 và một cụm 5, sau đó phóng to hoặc thu nhỏ một cấp, hai cụm giống nhau vẫn còn lại. Nhấp vào một trong số này ngay bây giờ renderer.getMarker(cluster) sẽ trả về giá trị rỗng. Nếu họ tái cluster sau khi phóng to, getMarker không phải là null.

Trình tạo mặc định của tôi bên dưới. Tôi đã kiểm tra điểm đánh dấu trên onClusteredRendered và nó không bao giờ rỗng. Đây có phải là một lỗi trong DefaultClusterRenderer hay tôi nên làm điều gì đó khác?

private class MyRenderer extends DefaultClusterRenderer<MyObject> { 

    private IconGenerator iconGenerator; 
    private float density; 

    public MyRenderer(Context context, GoogleMap map, ClusterManager<MyObject> clusterManager) { 
     super(context, map, clusterManager); 
     density = context.getResources().getDisplayMetrics().density; 
    } 

    @Override 
    protected void onBeforeClusterItemRendered(MyObject item, MarkerOptions markerOptions) { 
     markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_pin)); 
    } 

    @Override 
    protected void onBeforeClusterRendered(Cluster<MyObject> cluster, MarkerOptions markerOptions) { 
     if(iconGenerator == null) { 
      iconGenerator = new IconGenerator(getActivity()); 
      iconGenerator.setContentView(makeTextView(getActivity())); 
     } 
     iconGenerator.setBackground(makeBackground(false)); 

     markerOptions.icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon(String.valueOf(cluster.getSize())))); 
    } 

    @Override 
    protected void onClusterRendered(Cluster<MyObject> cluster, Marker marker) { 
     super.onClusterRendered(cluster, marker); 
     // Marker is never null here 

    } 

    @Override 
    protected boolean shouldRenderAsCluster(Cluster<MyObject> cluster) { 
     return cluster.getSize() > 1; 
    } 

    private ShapeDrawable makeBackground(boolean isClicked) { 
     ShapeDrawable background = new ShapeDrawable(new OvalShape()); 
     background.setColorFilter(ContextCompat.getColor(getActivity(), 
       isClicked ? R.color.cluster_marker_clicked : R.color.cluster_marker_unclicked), PorterDuff.Mode.SRC_ATOP); 

     return background; 
    } 

    private SquareTextView makeTextView(Context context) { 
     SquareTextView squareTextView = new SquareTextView(context); 

     ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(-2, -2); 
     squareTextView.setLayoutParams(layoutParams); 
     squareTextView.setTextColor(ContextCompat.getColor(getActivity(), R.color.white)); 

     squareTextView.setTypeface(Utils.getFontBold(getActivity())); 

     squareTextView.setId(com.google.maps.android.R.id.text); 
     int twelveDpi = (int) (12.0F * density); 
     squareTextView.setPadding(twelveDpi, twelveDpi, twelveDpi, twelveDpi); 

     return squareTextView; 
    } 

    public IconGenerator getIconGenerator(boolean isClicked) { 
     iconGenerator.setBackground(makeBackground(isClicked)); 
     return iconGenerator; 
    } 
} 

Khởi tạo các ClusterManager:

final ClusterManager<MyObject> mClusterManager = new ClusterManager<>(getActivity(), googleMap); 
    mClusterManager.addItems(items); 

    renderer = new CustomRenderer(getActivity(), googleMap, mClusterManager); 
    mClusterManager.setRenderer(renderer); 
    mClusterManager.cluster(); 

    mClusterManager.setOnClusterItemClickListener(this); 

    googleMap.setOnMarkerClickListener(mClusterManager); 

@antonio: khởi tạo này được làm việc cho tôi:

public class MapsActivity extends FragmentActivity 
     implements ClusterManager.OnClusterClickListener<MyObject> { 

    // ... 

    private void setUpClusterer() { 
     googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10)); 

     mClusterManager = new ClusterManager<MyObject>(this, googleMap); 
     mClusterManager.setOnClusterClickListener(this); 
     renderer = new MyRenderer(this, googleMap, mClusterManager); 
     mClusterManager.setRenderer(renderer); 

     googleMap.setOnCameraChangeListener(mClusterManager); 
     googleMap.setOnMarkerClickListener(mClusterManager); 

     addItems(); 
    } 

    private void addItems() { 
     // Set some lat/lng coordinates to start with. 
     double lat = 51.5145160; 
     double lng = -0.1270060; 

     // Add ten cluster items in close proximity, for purposes of this example. 
     for (int i = 0; i < 10; i++) { 
      double offset = i/60d; 
      lat = lat + offset; 
      lng = lng + offset; 
      MyObject offsetItem = new MyObject(lat, lng); 
      mClusterManager.addItem(offsetItem); 
     } 
    } 

    @Override 
    public boolean onClusterClick(final Cluster<MyObject> cluster) { 
     Marker marker = renderer.getMarker(cluster); 
     marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.my_newpin)); 

     return true; 
    } 
} 
+0

Tôi không thể tái tạo hành vi của bạn bằng ứng dụng demo. Bạn đang thêm các mục vào cụm sao như thế nào? Tôi sẽ đặt cược rằng đây là một vấn đề vòng đời hơn là một vấn đề với Renderer của bạn. Tôi cũng sẽ nói rằng bạn đang nhận được một null 'Marker' khi gọi' renderer.getMarker (cluster); 'bởi vì cluster bạn nhận được trên' onClusterClick (Cluster cluster) 'là null. Cụm – antonio

+0

không bao giờ là rỗng. Tôi cập nhật mã ở trên khi khởi tạo 'ClusterManager' – ono

+0

Ok, hãy để tôi kiểm tra hành vi của ví dụ của tôi bằng mã khởi tạo của bạn – antonio

Trả lời

3

Không thể lấy renderer.getMarker(cluster) để trả lại một điểm đánh dấu trong trường hợp đó ở trên. Một tác phẩm xung quanh là tạo ra:

Map <Cluster<MyObject>, Marker> clusterMarkerMap = new HashMap<>(); 

sau đó thêm chúng vào DefaultClusterRenderer gọi lại vì điểm đánh dấu không bao giờ là vô đó:

@Override 
protected void onClusterRendered(Cluster<MyObject> cluster, Marker marker) { 
    super.onClusterRendered(cluster, marker); 
    clusterMarkerMap.put(cluster, marker); 
} 

DefaultClusterManager xóa chúng khi thay đổi vị trí camera, lau cụm đánh dấu bản đồ trước khi nó tạo ra những cái mới:

googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { 
     @Override 
     public void onCameraChange(CameraPosition cameraPosition) { 
      // Clear the map here because the markers will be recreated 
      // when the manager is notified of a (zoom level) camera change 
      if(zoomLevelChanged) 
       clusterMarkerMap.clear(); 
      mClusterManager.onCameraChange(cameraPosition); 
     } 
    }); 

Bây giờ tôi có thể nhận được điểm đánh dấu thành công clusterMarkerMap.get(cluster)

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