高德地图Marker和Marker点击事件处理

界面上添加marker的相关操作

因为我做的景区里面有很多的景点,在显示景点类型的情况下就需要显示很多的景点marker,所以就在地图上面添加了景点的marker。下面是添加景点marker的代码。如果想要添加多个marker,循环遍历下面方法即可。

 /*** 往地图上添加marker*/public void addMarkersToMap(Context context, LatLng latlng, String title, int icon, int i,boolean isSpot) {if (mAmap != null) {View view = View.inflate(context, R.layout.marker_show, null);TextView textView = (TextView) view.findViewById(R.id.tv_marker_show);ImageView imageView = (ImageView) view.findViewById(R.id.iv_marker_show);imageView.setImageResource(icon);if ("".equals(title) || title == null) {textView.setVisibility(View.GONE);} else {textView.setVisibility(View.VISIBLE);}textView.setText(title);Bitmap bitmap = BitmapUtils.convertViewToBitmap(view);int radius = DensityUtil.dip2px(context, isSpot ? 225 : 170); markerOption = new MarkerOptions().position(latlng).draggable(true).title(i + "").setInfoWindowOffset(0, radius) //  需要慢慢调试情况.icon(BitmapDescriptorFactory.fromBitmap(bitmap));Marker marker = mAmap.addMarker(markerOption);// 将marker保存 方便后面清除mAllMarker.add(marker);// 释放资源bitmap.recycle();}}

因为我的marker比较复杂,不是单纯的一个图片就可以轻松的搞定,所以我这边自定义了view,然后将这个自定义的view打包成bitmap交给Amap。其实也可以不打包成bitmap,高德有api可以直接用view,但是它将view拿过去之后还是转成了图片的格式。

从开始new一个view的到转成bitmap都是属于给当前需要显示的view界面进行赋值,让marker在界面上显示的不一样。

radius:是我这边要显示的infowindow的y轴方向的偏移量,我这边由于UI切图问题和UI测试需要显示的问题导致我这边需要进行向下的偏移。

position:设置当前marker显示在界面的什么位置,即经纬度的传入。

draggable:当前marker是否可以拖动,true 可以拖动。

title:设置marker的主题。如果不设置title也不设置snippet的情况,点击这个marker是不会出现infowindow 我这边设置的position的编号,主要是我要根据marker里面保存的信息来找出当前显示的是哪一个景点的marker,那么在点击marker的时候就可以根据对应的marker显示对应的内容。

setInfoWindowOffset(int x,int y); x是横向的偏移量(正数表示向右偏移,负数表示向左偏移),y是竖向的偏移量(正数表示向下偏移,负数表示向上偏移)。

icon:将上面的view的bitmap传给地图

mAmap.addMarker(markerOption);

将上面对marker的配置添加到地图上,这是地图上面就显示了这个marker。

下面是我这边自定义的marker的样式。

添加marker的点击事件

        // marker 点击事件监听mAmap.setOnMarkerClickListener(mMarkerListener);

备注:一定要设置marker的title或者snippet,否则就算有点击事件,也不会调用getInfoWindow的方法。

点击事件的监听

在点击事件中不管界面有没有显示当前marker的infowindow,再次进行点击都会是显示infowindow。由于infowindow界面默认只显示一个,如果你点击其他的marker就会显示其他的,当前这个就会关闭掉。

/*** 设置marker的点击事件*/AMap.OnMarkerClickListener mMarkerListener = new AMap.OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker marker) {if (marker.isInfoWindowShown()) {marker.hideInfoWindow();} else {marker.showInfoWindow();}return true; // 返回:true 表示点击marker 后marker 不会移动到地图中心;返回false 表示点击marker 后marker 会自动移动到地图中心}};

infowindow的显示

mAmap.setInfoWindowAdapter(mAMapSpotAdapter); // 设置marker点击之后显示的infowindow界面

mAMapSpotAdapter 源代码如下:

AMap.InfoWindowAdapter mAMapSpotAdapter = new AMap.InfoWindowAdapter() {@Overridepublic View getInfoWindow(Marker marker) {if ("".equals(marker.getTitle()) || marker.getTitle() == null) {return null;}View infoContent = getLayoutInflater().inflate(R.layout.marker_click_spot_type, null);render(marker, infoContent);return infoContent;}@Overridepublic View getInfoContents(Marker marker) {if ("".equals(marker.getTitle()) || marker.getTitle() == null) {return null;}View infoContent = getLayoutInflater().inflate(R.layout.marker_click_spot_type, null);render(marker, infoContent);return infoContent;}private void render(Marker marker, View view) {// 界面的绘制加数据 当前是景点显示的infowindow 60 是正常情况 225  仅仅对景区景点的设置底部问题 带有箭头的正常情况下65RelativeLayout rl_all_info = view.findViewById(R.id.rl_all_info);RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(rl_all_info.getLayoutParams());int view_x = DpUtil.dp2px(mContext,200); // infowindow的宽度int bottom = DpUtil.dp2px(mContext,170); // 正常情况下底部偏移量问题int padding_view = DpUtil.dp2px(mContext,32)*2; // 正常情况下底部偏移量问题// 判断当前是上下左右哪一个地方的显示int type = showInfoWindowSpotLTRB(marker); // 1 marker 在屏幕的左边 2 marker 在屏幕的上面 3 marker 在屏幕的右边 4 marker 在屏幕的底部 5 左上  6 左下 7 右上  8  右下if (type == 1) { // top // 需要显示在顶部中间位置lp.setMargins(0,0, 0,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_center);} else if (type == 2 ){ // topleft // 顶部左边 需要显示在顶部最左边位置lp.setMargins(view_x-padding_view,0, 0,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_left);} else if (type == 3 ){ // topright // 顶部右边 需要显示在顶部最右边位置lp.setMargins(0,0, view_x-padding_view,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_right);} else if (type == 4 ){ // right // 右边 需要显示在右边中间位置lp.setMargins(0,0, view_x,  bottom/2);rl_all_info.setBackgroundResource(R.drawable.marker_spot_right_center);} else if (type == 5 ){ // left // 左边 需要显示在左边中间位置lp.setMargins(view_x,0, 0,  bottom/2);rl_all_info.setBackgroundResource(R.drawable.marker_spot_left_center);} else if (type == 6 ){ // leftBotttom // 底部左边 需要显示在底部最左边位置lp.setMargins(view_x-padding_view,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_left);} else if (type == 7 ){ // rightBottom // 底部右边 需要显示在底部最右边位置lp.setMargins(0,0, view_x-padding_view,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_right);} else if (type == 8 ){ // Bottom // 底部 需要显示在底部中间位置lp.setMargins(0,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_center);} else { // 正常情况下 显示在底部中间位置lp.setMargins(0,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_center);}// 设置属性rl_all_info.setLayoutParams(lp);// 音频播放点击事件RelativeLayout rlImg = view.findViewById(R.id.rl_img);// 景点图片显示 圆形图片显示RoundImageView ivScenicSpotImg = view.findViewById(R.id.iv_scenic_spot_img);// 播放的图片ImageView ivPlayImg = view.findViewById(R.id.iv_play_img);// 景点名称TextView tvTitle = view.findViewById(R.id.tv_title);// 景点距离TextView tvPosition = view.findViewById(R.id.tv_position);// 解说ImageView ivListen = view.findViewById(R.id.iv_intro);// 详请ImageView ivDetail = view.findViewById(R.id.iv_detail);int period = Integer.parseInt(marker.getTitle());ScenicSpotGuideBean.ScenicSpotListBean bean = mInfo.getScenicSpotList().get(period);tvTitle.setText(bean.getName());// 获取当前marker的经纬度LatLng markerLatLng = marker.getPosition();// 获取当前我的经纬度LatLng myLatLng = new LatLng(Constants.mLatitude,Constants.mLongitude);// 计算当前两个经纬度的距离问题float distance = AMapUtils.calculateLineDistance(markerLatLng, myLatLng);tvPosition.setText("距离" + AMapUtil.getFriendlyLength((int) distance));GlideUtil.loadImgRadius(ivScenicSpotImg, 0, bean.getPhotoUrl());// 点击事件// 播放点击事件rlImg.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 更新当前界面}});// 播放点击事件ivPlayImg.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 更新当前界面}});// 解说ivListen.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 更新当前界面}});// 详请ivDetail.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {marker.hideInfoWindow(); // 如果想要隐藏当前的infowindow就调用这个api}});}};

因为我这边的这个比较复杂,你们比较简单的可以不管render()里面的内容,我这边赋值是在render里面去做的赋值处理。

下面是点击之前和点击之后的界面变化。


因为滑动收到了限制。所以就会出现在边界的marker如果正常显示就会有一部分看不到,所以我这边根据当前marker在屏幕上的位置来判断当前marker所处位置是否可以显示正个infowindow的布局,如果会被隐藏一部分就做偏移处理,如marker在界面的右边就,往左偏移一定的值,就可以正常的看到全部的布局。

         RelativeLayout rl_all_info = view.findViewById(R.id.rl_all_info);RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(rl_all_info.getLayoutParams());int view_x = DpUtil.dp2px(mContext,200); // infowindow的宽度int bottom = DpUtil.dp2px(mContext,170); // 正常情况下底部偏移量问题int padding_view = DpUtil.dp2px(mContext,32)*2; // 正常情况下底部偏移量问题// 判断当前是上下左右哪一个地方的显示int type = showInfoWindowSpotLTRB(marker); // 1 marker 在屏幕的左边 2 marker 在屏幕的上面 3 marker 在屏幕的右边 4 marker 在屏幕的底部 5 左上  6 左下 7 右上  8  右下if (type == 1) { // top // 需要显示在顶部中间位置lp.setMargins(0,0, 0,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_center);} else if (type == 2 ){ // topleft // 顶部左边 需要显示在顶部最左边位置lp.setMargins(view_x-padding_view,0, 0,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_left);} else if (type == 3 ){ // topright // 顶部右边 需要显示在顶部最右边位置lp.setMargins(0,0, view_x-padding_view,  0);rl_all_info.setBackgroundResource(R.drawable.marker_spot_top_right);} else if (type == 4 ){ // right // 右边 需要显示在右边中间位置lp.setMargins(0,0, view_x,  bottom/2);rl_all_info.setBackgroundResource(R.drawable.marker_spot_right_center);} else if (type == 5 ){ // left // 左边 需要显示在左边中间位置lp.setMargins(view_x,0, 0,  bottom/2);rl_all_info.setBackgroundResource(R.drawable.marker_spot_left_center);} else if (type == 6 ){ // leftBotttom // 底部左边 需要显示在底部最左边位置lp.setMargins(view_x-padding_view,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_left);} else if (type == 7 ){ // rightBottom // 底部右边 需要显示在底部最右边位置lp.setMargins(0,0, view_x-padding_view,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_right);} else if (type == 8 ){ // Bottom // 底部 需要显示在底部中间位置lp.setMargins(0,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_center);} else { // 正常情况下 显示在底部中间位置lp.setMargins(0,0, 0,  bottom);rl_all_info.setBackgroundResource(R.drawable.marker_spot_bottom_center);}// 设置属性rl_all_info.setLayoutParams(lp);

这一部分的代码是做布局的偏移显示,我分成八种情况分别是:顶部,顶部左边,顶部右边,左边,右边,底部,底部左边,底部右边。如果你也需要做这样的操作,你可以根据你的布局进行详细的偏移。如果要显示在marker的底部,需要在最开始的时候设置marker的setInfoWindowOffset的y方向的偏移量默认显示在底部,不然后面改margin是不能浮动到marker的底部的。

         // 获取当前marker的经纬度LatLng markerLatLng = marker.getPosition();// 获取当前我的经纬度LatLng myLatLng = new LatLng(Constants.mLatitude,Constants.mLongitude);// 计算当前两个经纬度的距离问题float distance = AMapUtils.calculateLineDistance(markerLatLng, myLatLng);tvPosition.setText("距离" + AMapUtil.getFriendlyLength((int) distance));

这个是根据我当前的位置和marker的位置计算出我与当前景点的距离。

/***  获取infowindow应该显示为位置* @return type 0 表示不做更改 1 顶部 2 顶部左边 3 顶部右边 4 右边 5 左边 6 底部左边 7 顶部右边 8 底部*/private int showInfoWindowSpotLTRB(Marker marker){Point markerPoint = mAmap.getProjection().toScreenLocation(marker.getPosition()); // 返回一个从地图位置转换来的屏幕位置int type = 0;int screen_X = getResources().getDisplayMetrics().widthPixels;int screen_Y = getResources().getDisplayMetrics().heightPixels;int marker_x = markerPoint.x;int marker_y = markerPoint.y;int view_x = DpUtil.dp2px(mContext,152)/2; // infowindow的宽度int view_y = DpUtil.dp2px(mContext,108)/2; // infowindow的高度int top_y = DpUtil.dp2px(mContext,103);int Bottom_y = DpUtil.dp2px(mContext,135);if (((screen_X-marker_x) < view_x)){ // 横向判断当前marker位置是否是在右边 表示在右边// 当前已经在右边了 判断有没有在顶部if ((screen_Y - marker_y) < (view_y + Bottom_y)){ // 当前在底部 右边底部type = 7;} else if ((marker_y-top_y) < view_y){ // 当前在顶部 右边顶部type = 3;} else { // 右边type = 4;}} else if (marker_x < view_x){ // 当前在左边if ((screen_Y - marker_y) < (view_y + Bottom_y)){ // 当前在底部 左边底部type = 6;} else if ((marker_y-top_y) < view_y){ // 当前在顶部 左边顶部type = 2;} else { // 左边type = 5;}} else if ((marker_y-top_y) < view_y){ // 当前在顶部 顶部type = 1;} else if ((screen_Y - marker_y) < (view_y + Bottom_y)){ // 当前在底部 底部type = 8;} else { //不做操作type = 0;}return type;}

上面这个方法是计算当前marker在屏幕的什么位置。

mAmap.getProjection().toScreenLocation(marker.getPosition());

这个根据marker获取屏幕位置时高德地图官方提供的。

Android 高德地图Marker和Marker点击事件处理相关推荐

  1. Android 高德地图(带有定位和点击显示经度纬度)

    Android高德地图测试,如下: 1.Android高德地图Demo地址下载:       下载android高德地图Demo 1.2 Android定位SDK 一键下载 1.3 下载好的文件zip ...

  2. android高德地图多个mark点击,Android ---------高德卫星地图绘制多个点和点的点击事件自定义弹窗...

    最近开发中,遇到一个多个点绘制,并实现点击事件,出现自定义窗口显示相关信息等功能,所以写了这篇博客. 从后台请求数据,得到多个经纬度,然后绘制在地图上,并实现点击,出现相关信息(自定义弹框实现) 先来 ...

  3. android高德marker添加点击,高德地图上添加marker,给每一个marker添加点击事件。...

    高德地图上添加marker,给每一个marker添加点击事件. 高德地图上添加marker,给每一个marker添加点击事件.javascript var watch = [] $.ajax({ ty ...

  4. 只用一个marker 替换 高德_Android基于高德地图完全自定义Marker的实现方法

    前言 相信做地图社交类APP开发的大家都知道,一般情况下,为了整体的美观和用户体验度,我们需要定制化Marker的样式.本文中实现的方式都是基于高德地图的,百度地图也类似,大家可以照葫芦画瓢,废话不多 ...

  5. 高德地图sdk设置marker并且将设置为地图中心

    高德地图sdk设置marker并且将设置为地图中心,直接在官方demo里改,授权key需要改为自己的. <!doctype html> <html> <head>& ...

  6. Android高德地图自定义Markers的例子

    下文为各位重点介绍关于Android高德地图自定义Markers的例子,希望这篇文章能够让各位理解到Android高德地图自定义Markers的方法. 之前的博客里说了地图的嵌入和定位,今天就说说在地 ...

  7. Android 高德地图给指定坐标显示图片,以及聚合显示

    官网实例请点击:Android 高德地图聚合官网 下面是一个案例: 效果图: MainActivity public class MainActivity extends AppCompatActiv ...

  8. Android 高德地图自定义线路规划选择方案之后按照方案进行导航

    Android 高德地图自定义线路规划选择方案之后按照方案进行导航 因为我这边导航需求的问题,导致我这边不能使用高德地图官方的线路规划和导航.所以我这边线路规划和导航界面都是根据高德地图那边给的api ...

  9. Android高德地图自定义Mark并实现聚合效果

    Android高德地图自定义Mark并实现聚合效果 起因:公司本来项目里面用到了高德地图,然后最近老板看见别人的APP里面有个聚合的这个功能,老板:"这个效果能不能实现,我也要!" ...

  10. Android 高德地图中路线规划绘制界面线路

    Android 高德地图中路线规划绘制界面线路 下面代码是根据很多的经纬度的点,绘制出直线的线路.比较死板 /*** 绘制景区的路线*/private void setRouteInfo(List&l ...

最新文章

  1. 如何成为一名数据工程师
  2. windows python3.2 shell环境(python叫做解释器)
  3. 让 Windows 7 定时待机
  4. 第97:一文读懂协方差与协方差矩阵
  5. android 多级分组,android 二级菜单(类似QQ分组)
  6. MAC 设置$PATH 关闭terminal后就失效 解决方案
  7. 汇编语言:实现大小写字母转换
  8. 小tips:善用页面的base类
  9. 世界首个!AI农作物病害检测竞赛火热进行中 | AI Challenger 全球AI挑战赛
  10. CATransition 动画
  11. ajax请求后台php数据时查看报错parse error
  12. sklearn 模型选择和评估
  13. Django中ORM之创建模型
  14. coreldraw sp2精简版 x4_coreldraw x4 sp2 精简版
  15. 运维第二篇:Docker--Harbor私有镜像仓库搭建
  16. flex布局(弹性布局)
  17. php的电阻率是多少,PTF65517KBT-10B14
  18. mysql slave_pending_jobs_size_max_3分钟解决MySQL 1864 主从错误
  19. 计算机软考高级 天津落户,官宣:软考高级可作为高级职称人才引进落户上海...
  20. centos系统使用pptpd搭建在windows客户端的vpn服务器

热门文章

  1. 蓝狐SEO关键词按天计费系统_seo扣费系统源码
  2. Halcon之图像采集II
  3. 都在说云原生?到底什么是云原生?
  4. 2429: [HAOI2006]聪明的猴子
  5. Java-编辑图片,添加文字
  6. 贪吃蛇小游戏制作(3)
  7. 变限积分 matlab,积分变限函数
  8. 安卓u盘格式化工具apk_你听说过badusb么,我扔个U盘你敢捡么?(文末附阿里云盘最新邀请码)...
  9. Compose系列 五 副作用 side-effect
  10. 网络文件共享服务(一)