上一篇博文(基于Baidu Map InfoWindow的消息交互)尝试使用Baidu Map InfoWindow来显示用户发送的消息,但由于Map一次只能显示一个InfoWindow(InfoWindow的初衷是marker的弹出框),所以无法实现群聊效果。
之前也有看,过将消息转换为marker image来完成多条消息显示的方式,但每次都需要根据消息内容生成不同大小的marker image,且还需考虑分辨率的因素,个人认为比较麻烦。
因而,本文采用最简单的思路:当有用户发送消息时,该用户头像变化,点击头像弹出InfoWindow,显示消息内容。
需要说明的是,本文的实现,还是以RadarUploadInfo对象作为消息上行载体,RadarNearbyInfo对象作为消息下行载体,但两对象并不合适。原因在于,APP需要使用Baidu Map的周边雷达扫描获取RadarNearbyInfo对象,自动扫描间隔最小为1秒。RadarUploadInfo对象,自动上传时间间隔最小为5秒(手动上传虽然无间隔限制,但从消息发送至接收,大于需要2~3秒),因此,实时性不好。所以,本文仅将重点聚焦在功能的实现。消息载体,我们之后再做替换。
进入正题,我们分三步来实现功能。
(1)marker图标变化的实现
MarkerOptions.MarkerAnimateType animateType= MarkerOptions.MarkerAnimateType.none ;
for (RadarNearbyInfo Info : m_NearbyInfoList) {
if(Info.comments==null || Info.comments.equals("")){
animateType=MarkerOptions.MarkerAnimateType.none;
}else{
animateType=MarkerOptions.MarkerAnimateType.grow;
}
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.ic_marker_blue);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(Info.pt)
.icon(bitmap)
.title(Info.comments)
.animateType(animateType);
Bundle bundle = new Bundle();
bundle.putSerializable("Info", Info);
//在地图上添加Marker,并显示
Marker marker=(Marker) (m_Map.addOverlay(option));
marker.setExtraInfo(bundle);
}
SDK为添加层Overlay提供了三种animate形式,分别为none,grow和drop。相对于grow,相信你不会喜欢drop的。
由于Marker继承于Overlay,因此可以强行转换。
为marker设置bundle,是为之后点击事件获取数据做准备。
关于OverlayOption的title,一直不知道有何用处,显示或是数据传递?有知道的同学,望指教。
(2)marker的点击监听事件的实现
对BaiduMap对象添加marker点击监听器。
m_Map.setOnMarkerClickListener(this);
Activity实现BaiduMap.OnMarkerClickListener接口
public class AroundActivity extends AppCompatActivity implements BDLocationListener, RadarSearchListener, RadarUploadInfoCallback, BaiduMap.OnMarkerClickListener {
...
}
BaiduMap.OnMarkerClickListener接口只有一个onMarkerClick()方法需要实现。
public boolean onMarkerClick(Marker marker) {
RadarNearbyInfo Info=(RadarNearbyInfo) marker.getExtraInfo().get("Info");
showInfoWindow(Info.pt,Info.comments);;
}
跟其他手势事件一样,若返回false,将有该view的父容器处理点击事件。若返回true,则代表该view已经完成了相应事件的处理。
private void showInfoWindow(LatLng pt, String comments){
m_Map.hideInfoWindow();
InfoWindow infoWindow;
TextView textView = new TextView(getApplicationContext());
textView.setBackgroundResource(R.drawable.chat);
textView.setPadding(30, 20, 30, 50);
textView.setText(comments);
infoWindow =new InfoWindow(textView,pt,DEFAULT_INFO_WINDOW_Y_OFFSET);
infoWindowList.add(infoWindow);
Log.i(TAG, "showInfoWindow: comments = "+comments);
m_Map.showInfoWdow);
}
(3)点击空白,InfoWindow消失
对BaiduMap对象添加点击监听器。
m_Map.setOnMapClickListener(this);
Activity实现BaiduMap.OnMapClickListener接口
public class AroundActivity extends AppCompatActivity implements BDLocationListener, RadarSearchListener, RadarUploadInfoCallback, BaiduMap.OnMarkerClickListener, BaiduMap.OnMapClickListener {
...
}
BaiduMap.OnClickListener接口有两个方法需要实现。
@Override
public void onMapClick(LatLng latLng) {
m_Map.hideInfoWindow();
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
此处,我们仅实现onMapClick()方法。onMapPoiClick()方法将Poi点击事件交由父容器处理。
至此,交互完成。