【问题标题】:Updating cluster markers pictures更新集群标记图片
【发布时间】:2019-11-27 09:43:37
【问题描述】:

我正在创建一个社交媒体应用程序,帮助人们找到他们的朋友。我想要包括的一项功能是用户能够选择他们的个人资料图片。但是,我在更新集群标记图片时遇到问题。基本上我使用volly 连接到数据库以获取最新的用户数据。当我单击一个按钮时会调用此方法。我做了类似的事情来成功更改用户的个人资料图片。如果有人能给出很好的指点,我不确定为什么这不起作用。

private void updateMapMarkers(){
        //mMap.clear(); not sure if i need to do this or not
        //mClusterManager.clearItems(); also tried this
        mClusterManager.removeItems(mClusterMarkers);
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        String url = "http://some ip address/update_everyones_cords.php?THIS_USER_ID=" + MainActivity.THIS_USER_ID;
        JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, url,null,
                new Response.Listener<JSONArray>() {
                    public void onResponse(JSONArray response){
                        try {
                            ArrayList<ClusterMarker> mClusterMarkersUpdated = new ArrayList<>();
                            for (int i = 0; i < response.length(); i++) {
                                JSONObject rec = response.getJSONObject(i);
                                String userName = rec.getString("userName");
                                String profilePicture = rec.getString("profilePicture");
                                int userID = rec.getInt("ID");

                                int avatar;
                                if (profilePicture.equals("default")){
                                    avatar = R.drawable.androidlogo;
                                } else {
                                    avatar = Integer.parseInt(THIS_USER_PIC);
                                }
                                if (userID == THIS_USER_ID){
                                    ClusterMarker thisUser = new ClusterMarker(
                                            new LatLng(THIS_CORDSV1, THIS_CORDSV2),
                                            THIS_USER_NAME,
                                            "This is you",
                                            avatar,
                                            THIS_USER_ID);
                                    mClusterManager.addItem(thisUser);
                                    mClusterMarkersUpdated.add(thisUser);
                                    Log.wtf(TAG,userName);
                                } else {
                                    Log.wtf(TAG,userName);
                                    ClusterMarker thisUser = new ClusterMarker(
                                            new LatLng(THIS_CORDSV1, THIS_CORDSV2),
                                            userName,
                                            "determine route to",
                                            avatar,
                                            userID);
                                    mClusterManager.addItem(thisUser);
                                    mClusterMarkersUpdated.add(thisUser);
                                }
                            }
                            mClusterMarkers = mClusterMarkersUpdated;
                        } catch (JSONException e) {
                            Toast.makeText(MainActivity.this, "jason obj ex:" + e.toString(), Toast.LENGTH_SHORT).show();
                        }
                    }
                }, new Response.ErrorListener() {
            public void onErrorResponse(VolleyError er){
                Toast.makeText(MainActivity.this, "volley error:" + er.toString(), Toast.LENGTH_LONG).show();
            }
        }
        ); queue.add(jsObjRequest);
        mClusterManager.cluster();
    }


我也试过这样的东西,也没有用。当我说它不起作用时,至少对于上述方法,我没有得到任何错误,只是一张没有标记的空白地图。对于下面的尝试,什么都没有发生。


int defaultImage = R.drawable.androidlogo;
mImageUrlsLarger.add(defaultImage + "");
mClusterMarkers.get(i).setIconPicture(defaultImage);
mClusterManager.cluster();

【问题讨论】:

  • 你可以试试自定义ClusterRenderer

标签: java android markerclusterer


【解决方案1】:
    public class CustomClusterItem implements ClusterItem {


    private final LatLng position;
    private String title;
    private String snippet;
    private String tag;
    private String imageUrl;

    public CustomClusterItem(double lat, double lng) {
        this.position = new LatLng(lat, lng);
    }

  //getters and setters
}

CustomClusterRenderer.Java

public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> implements GoogleMap.OnCameraIdleListener {

private CameraIdleListener listener;
//used to keep strong reference to 'Target' object, otherwise objects get garbage collected and picasso will fail to load image
private List<Target> targetList = new ArrayList<>();
private IconGenerator greenIconGenerator;
private ImageView greenImageView;
private Context context;

public CustomClusterRenderer(Context context, GoogleMap map, ClusterManager<CustomClusterItem> clusterManager) {
    super(context, map, clusterManager);
    this.context = context;
    prepareImageViews(context);
    prepareIconGenerator(context);
}

public void setCameraIdleListener(CameraIdleListener cameraIdleListener) {
    this.listener = cameraIdleListener;
}

public void clearTargetList() {
    targetList.clear();
}

private void prepareIconGenerator(Context context) {
    greenIconGenerator = new IconGenerator(context);
    greenIconGenerator.setColor(ContextCompat.getColor(context, R.color.priority_green));
    greenIconGenerator.setContentView(greenImageView);
}

private void prepareImageViews(Context context) {
    final int mDimension = (int) context.getResources().getDimension(R.dimen._30sdp);
    final int padding = (int) context.getResources().getDimension(R.dimen._8sdp);
    greenImageView = new ImageView(context);
    greenImageView.setLayoutParams(new ViewGroup.LayoutParams(mDimension, mDimension));
    greenImageView.setPadding(padding, padding, padding, padding);
}




@Override
protected void onBeforeClusterItemRendered(final CaseClusterItem item,
                                           final MarkerOptions markerOptions) {
    Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_action_settings);
    getImageView(item.getPriority()).setImageBitmap(largeIcon);
    Bitmap icon = greenIconGenerator.makeIcon();
    markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
}


@Override
protected void onClusterItemRendered(final CustomClusterItem clusterItem,
                                     final Marker marker) {
    super.onClusterItemRendered(clusterItem, marker);
    Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            //TODO - find the root cause for IllegalArgumentException
            try {
                greenImageView.setImageBitmap(bitmap);
                Bitmap icon = greenIconGenerator.makeIcon();
                marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
            } catch (IllegalArgumentException e) {
                LogHelper.printErrorLog("Not sure about the cause of issue, need to rectify");
            }
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
        }
    };

    if (!TextUtils.isEmpty(clusterItem.getImageUrl())) {
        getPicasso().load(clusterItem.getImageUrl()).resize(60, 60).into(target);
        targetList.add(target);
    }
}

@Override
public void onCameraIdle() {
    if (listener != null) {
        listener.onCameraIdle();
    }
}


public interface CameraIdleListener {
    void onCameraIdle();
}

}

HomeFragment.Java

public class HomeFragment extends BaseFragment implements OnMapReadyCallback, GoogleMap.OnCameraIdleListener, GoogleMap.OnMarkerClickListener, ClusterManager.OnClusterItemClickListener<CustomClusterItem>, ClusterManager.OnClusterClickListener<CustomClusterItem>, CustomClusterRenderer.CameraIdleListener{


private ClusterManager<CustomClusterItem> clusterManager;
private CustomClusterRenderer clusterRenderer;





private void generateMarkerFromCase(List<CustomListResponse.DataBean.CaseBean> caseList) {
    clusterRenderer.clearTargetList();
    if (caseList == null) {
        ToastHelper.show("No cases found.");
        return;
    }
    for (final CustomListResponse.DataBean.CustomBean caseBean : caseList) {
        try {
            final double lat = Double.parseDouble(caseBean.getLat());
            final double lng = Double.parseDouble(caseBean.getLongX());
            String markerUrl;
            markerUrl = caseBean.getParent_category().getImage();
            if (markerUrl == null) {
                markerUrl = caseBean.getCategory().getImage();
            }
            CustomClusterItem clusterItem = new CustomClusterItem(lat, lng);
            clusterItem.setTag(caseBean.getId());
            clusterItem.setImageUrl(markerUrl);
            clusterItem.setPriority(caseBean.getPriority());
            clusterManager.addItem(clusterItem);
        } catch (NumberFormatException e) {
            LogHelper.printErrorLog("Lat or Lng is null, bcz app is still in development mode : " + caseBean.getTitle() + " , Des - " + caseBean.getDescription());
        }
    }
    clusterManager.cluster();
    zoomOutMap();
}


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


    clusterManager = new ClusterManager<>(getContext(), googleMap);
    clusterManagerAlgorithm = new NonHierarchicalDistanceBasedAlgorithm();
    clusterManager.setAlgorithm(clusterManagerAlgorithm);
    clusterRenderer = new CustomClusterRenderer(getContext(), googleMap, clusterManager);
    clusterRenderer.setCameraIdleListener(this);
    clusterManager.setRenderer(clusterRenderer);

    this.googleMap.setOnCameraIdleListener(clusterManager);
    this.googleMap.setOnMarkerClickListener(clusterManager);
    clusterManager.setOnClusterItemClickListener(this);
    clusterManager.setOnClusterClickListener(this);

}

}

【讨论】:

  • 我实际上使用 CustomClusterRenderer 来更新我的标记位置。什么方法负责更新图片?
  • onClusterItemRendered() 函数负责添加图片到marker
  • 为什么有两个参数?一个 customClusterItem 和一个标记? customClusterItem 不是标记吗?我没有看到制造商参数的目的。
  • 该函数被 DefaultClusterRenderer 类覆盖
  • CaseClusterItem 包含标记图标、标题等数据,可以用您的数据类替换
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
相关资源
最近更新 更多