Android高德地图自定义Mark并实现聚合效果
起因:公司本来项目里面用到了高德地图,然后最近老板看见别人的APP里面有个聚合的这个功能,老板:“这个效果能不能实现,我也要!”没有办法因为以前没有做过高德地图点聚合这个东西,然后只能勉强的答应下来可以,然后就去看了高德开发者平台上面的给我说的点聚合,看完以后(星星你个大星星),能不能写例子,要是像他那个说的那个简单我真的就是谢谢了!没办法只能去下载高德地图提供给我的dome了,然后看了dome以后在dome的基础上面进行改造,然后就出来了。
先看一下效果
然后我们先看下我们下载下来的高德地图的dome 的结构
打红的框子的就是高德dome的东西,然后查看他的dome你会发现主要的类ClusterOverlay这个类。
然后我们来分析一下dome里面需要我们改的东西。然后我会被解释写在里面
先看一看这个类的构造
/*
* amap 地图的对象
* clusterItems 这个就是数据的集合
* clusterSize 聚合范围的大小(指点像素单位距离内的点会聚合到一个点显示)
*/
public ClusterOverlay(AMap amap,
List<ClusterItem> clusterItems,
int clusterSize,
Context context) {...}
再看下添加点的方法
/**
* 将聚合元素添加至地图上
*/
private void addClusterToMap(List<Cluster> clusters) {
ArrayList<Marker> removeMarkers = new ArrayList<>();
removeMarkers.addAll(mAddMarkers);
//点聚合的动画
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
MyAnimationListener myAnimationListener = new MyAnimationListener(removeMarkers);
for (Marker marker : removeMarkers) {
marker.setAnimation(alphaAnimation);
marker.setAnimationListener(myAnimationListener);
marker.startAnimation();
}
//便利一下数据类然后开始添加我们的点
for (Cluster cluster : clusters) {
addSingleClusterToMap(cluster);
}
}
private void addSingleClusterToMap(Cluster cluster) {
MyLoge.addLoge("addSingleClusterToMap", cluster.getClusterItems().get(cluster.getClusterCount() - 1).getUrl() + " -=-=-= " + cluster.getClusterCount());
LatLng latlng = cluster.getCenterLatLng();
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.anchor(0.5f, 0.5f)
.icon(getBitmapDes(cluster.getClusterCount(), cluster.getClusterItems().get(cluster.getClusterCount() - 1).getUrl()))
.position(latlng);
Marker marker = mAMap.addMarker(markerOptions);
marker.setAnimation(mADDAnimation);
marker.setObject(cluster);
marker.startAnimation();
cluster.setMarker(marker);
mAddMarkers.add(marker);
}
private BitmapDescriptor getBitmapDes(int num, int url) {
final BitmapDescriptor[] bitmapDescriptor ;
if (bitmapDescriptor[0] == null) {
customizeMarkerIcon(url, new OnMarkerIconLoadListener() {
@Override
public void markerIconLoadingFinished(View view) {
//把view转橙bitmap
bitmapDescriptor[0] = BitmapDescriptorFactory.fromView(view);
}
});
}
return bitmapDescriptor[0];
}
//自定义头像
private void customizeMarkerIcon(int url, OnMarkerIconLoadListener listener) {
//头像的布局
final View markerView = LayoutInflater.from(mContext).inflate(R.layout.amap_head_layout, null);
final YYCodeImageView friendTouxiang = markerView.findViewById(R.id.img);
final ImageView icon = markerView.findViewById(R.id.icon);
//皇冠的图标
RelativeLayout putongHead = markerView.findViewById(R.id.putongHead);
RelativeLayout chat_head = markerView.findViewById(R.id.chat_head);
RelativeLayout waimai_layout = markerView.findViewById(R.id.waimai_layout);
putongHead.setVisibility(View.VISIBLE);
chat_head.setVisibility(View.GONE);
waimai_layout.setVisibility(View.GONE);
icon.setVisibility(View.VISIBLE);
icon.setImageResource(R.drawable.map_icon_emoticon_insensitivity);
friendTouxiang.getBigCircleImageView().setImageResource(url);
//头像完成以后走这个头像完成的监听
listener.markerIconLoadingFinished(markerView);
}
//marker加载完成的回调
private interface OnMarkerIconLoadListener {
void markerIconLoadingFinished(View view);
}
再看一下mark的点击事件
//点击事件
@Override
public boolean onMarkerClick(Marker arg0) {
if (mClusterClickListener == null) {
return true;
}
Cluster cluster = (Cluster) arg0.getObject();
if (cluster != null) {
// cluster.getClusterItems() 点击的那个点的数据
mClusterClickListener.onClick(arg0, cluster.getClusterItems());
return true;
}
return false;
}
然后我们就来插入假数据看看点聚合的效果在地图加载完成的监里面进行添加点这里随机了100个点,然后2种样式的图片
@Override
public void onMapLoaded() {
//添加测试数据
new Thread() {
public void run() {
List<ClusterItem> items = new ArrayList<ClusterItem>();
//随机10000个点
for (int i = 0; i < 100; i++) {
double lat = Math.random() + 39.474923;
double lon = Math.random() + 116.027116;
LatLng latLng = new LatLng(lat, lon, false);
RegionItem regionItem;
int index = i%2;
MyLoge.addLoge("inidsdokookoko",index+" index-=-=-");
if (index == 0) {
regionItem = new RegionItem(latLng,
"test" + i, R.drawable.test_video_bj);
}else {
regionItem = new RegionItem(latLng,
"test" + i, R.drawable.wbf_test_img_two);
}
items.add(regionItem);
}
mClusterOverlay = new ClusterOverlay(mAMap, items,
dp2px(WbfTestThreeActivity.this, clusterRadius),
WbfTestThreeActivity.this);
// mClusterOverlay.setClusterRenderer(WbfTestThreeActivity.this);
mClusterOverlay.setOnClusterClickListener(WbfTestThreeActivity.this);
}
}.start();
}
这个就是回调的点击事件,就是点击每个头像的点击事件clusterItems这个东西是一个集合可以拿到集合的,点击一个地图上的mark,clusterItems这个集合的长度是多少你就可以知道这个mark聚合了多少个点
@Override
public void onClick(Marker marker, List<ClusterItem> clusterItems) {
MyLoge.addLoge("ClusterItem111111",clusterItems.size()+" -=--=-= "+
clusterItems.get(clusterItems.size()-1).getUrl());
}
添加点的时候我们取的是集合的最后一项的图片显示的,所以我们上面的监听的事件也就是取的clusterItems集合的最后一项。
下面放一个我的源码包