Android 百度地图 SDK v3.0.0 (三) 加入覆盖Marker与InfoWindow使用

转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/37737213

上篇博客已经实现了地图的定位以及结合了方向传感器用户路痴定位方向,假设你还不清楚,请查看:Android 百度地图 SDK v3.0.0 (二) 定位与结合方向传感器。本章会教大家怎样加入覆盖物,实现周边搜索,以及对覆盖物的点击出现介绍等效果。

效果图:

Android 百度地图 SDK v3.0.0 (三) 加入覆盖Marker与InfoWindow使用

我们的需求是。当用户点击衣食住行,或者对对附近搜索是。从server返回数据(经纬度,商家信息,介绍等)。然后动态生成覆盖物,实现上述效果。关于图片,因为手机上的内存的有限性,全部的图片下载完毕都应该存入预设的缓存中。比如LruCache。然后须要的时候从缓存取。缓存没有,下载完毕放入缓存;即实现全部的图片所占的内存永远不会超过缓存预设的内存值,当然了本篇的重点不是这个,我直接拿了几张图片加入我们的项目中模拟。

1、承载数据的实体

我们从server返回的数据部分,终于可能是个Json数组。我们须要转换为实体集合,即以下的Info.java:

package com.zhy.zhy_baidu_ditu_demo03;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Info implements Serializable
{
	private static final long serialVersionUID = -758459502806858414L;
	/**
	 * 精度
	 */
	private double latitude;
	/**
	 * 纬度
	 */
	private double longitude;
	/**
	 * 图片ID,真实项目中可能是图片路径
	 */
	private int imgId;
	/**
	 * 商家名称
	 */
	private String name;
	/**
	 * 距离
	 */
	private String distance;
	/**
	 * 赞数量
	 */
	private int zan;

	public static List<Info> infos = new ArrayList<Info>();

	static
	{
		infos.add(new Info(34.242652, 108.971171, R.drawable.a01, "英伦贵族小旅馆",
				"距离209米", 1456));
		infos.add(new Info(34.242952, 108.972171, R.drawable.a02, "沙井国际洗浴会所",
				"距离897米", 456));
		infos.add(new Info(34.242852, 108.973171, R.drawable.a03, "五环服装城",
				"距离249米", 1456));
		infos.add(new Info(34.242152, 108.971971, R.drawable.a04, "老米家泡馍小炒",
				"距离679米", 1456));
	}

	public Info()
	{
	}

	public Info(double latitude, double longitude, int imgId, String name,
			String distance, int zan)
	{
		super();
		this.latitude = latitude;
		this.longitude = longitude;
		this.imgId = imgId;
		this.name = name;
		this.distance = distance;
		this.zan = zan;
	}

	public double getLatitude()
	{
		return latitude;
	}

	public void setLatitude(double latitude)
	{
		this.latitude = latitude;
	}

	public double getLongitude()
	{
		return longitude;
	}

	public void setLongitude(double longitude)
	{
		this.longitude = longitude;
	}

	public String getName()
	{
		return name;
	}

	public int getImgId()
	{
		return imgId;
	}

	public void setImgId(int imgId)
	{
		this.imgId = imgId;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getDistance()
	{
		return distance;
	}

	public void setDistance(String distance)
	{
		this.distance = distance;
	}

	public int getZan()
	{
		return zan;
	}

	public void setZan(int zan)
	{
		this.zan = zan;
	}

}

我直接在实体类中声明了一个静态列表集合,模拟从server返回的数据Info.infos。

2、地图中动态加入Overlay

为了方便,我把button都放在menu菜单中:

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
	switch (item.getItemId())
	{
	 case R.id.id_menu_map_addMaker:
		addInfosOverlay(Info.infos);
		break;
	...	
	}	
}

/**
	 * 初始化图层
	 */
	public void addInfosOverlay(List<Info> infos)
	{
		mBaiduMap.clear();
		LatLng latLng = null;
		OverlayOptions overlayOptions = null;
		Marker marker = null;
		for (Info info : infos)
		{
			// 位置
			latLng = new LatLng(info.getLatitude(), info.getLongitude());
			// 图标
			overlayOptions = new MarkerOptions().position(latLng)
					.icon(mIconMaker).zIndex(5);
			marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
			Bundle bundle = new Bundle();
			bundle.putSerializable("info", info);
			marker.setExtraInfo(bundle);
		}
		// 将地图移到到最后一个经纬度位置
		MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
		mBaiduMap.setMapStatus(u);
	}

能够看到,我们迭代加入了Overlay。然后在返回的Marker中设置了商家的信息,用户用户对Marker的点击时,拿到商家数据生成具体信息布局。

3、为地图上的Marker加入点击事件:

//对Marker的点击
		mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
		{
			@Override
			public boolean onMarkerClick(final Marker marker)
			{
				//获得marker中的数据
				Info info = (Info) marker.getExtraInfo().get("info");
				
				InfoWindow mInfoWindow;
				//生成一个TextView用户在地图中显示InfoWindow
				TextView location = new TextView(getApplicationContext());
				location.setBackgroundResource(R.drawable.location_tips);
				location.setPadding(30, 20, 30, 50);
				location.setText(info.getName());
				//将marker所在的经纬度的信息转化成屏幕上的坐标
				final LatLng ll = marker.getPosition();
				Point p = mBaiduMap.getProjection().toScreenLocation(ll);
				Log.e(TAG, "--!" + p.x + " , " + p.y);
				p.y -= 47;
				LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
				//为弹出的InfoWindow加入点击事件
				mInfoWindow = new InfoWindow(location, llInfo,
						new OnInfoWindowClickListener()
						{

							@Override
							public void onInfoWindowClick()
							{
								//隐藏InfoWindow
								mBaiduMap.hideInfoWindow();
							}
						});
				//显示InfoWindow
				mBaiduMap.showInfoWindow(mInfoWindow);
				//设置具体信息布局为可见
				mMarkerInfoLy.setVisibility(View.VISIBLE);
				//依据商家信息为具体信息布局设置信息
				popupInfo(mMarkerInfoLy, info);
				return true;
			}
		});

依据商家的信息Info.java为具体信息布局中的控件加入数据(记得生成TextView的时候,先设置背景,再设置padding,不然可能会失效~~~)

/**
	 * 依据info为布局上的控件设置信息
	 * 
	 * @param mMarkerInfo2
	 * @param info
	 */
	protected void popupInfo(RelativeLayout mMarkerLy, Info info)
	{
		ViewHolder viewHolder = null;
		if (mMarkerLy.getTag() == null)
		{
			viewHolder = new ViewHolder();
			viewHolder.infoImg = (ImageView) mMarkerLy
					.findViewById(R.id.info_img);
			viewHolder.infoName = (TextView) mMarkerLy
					.findViewById(R.id.info_name);
			viewHolder.infoDistance = (TextView) mMarkerLy
					.findViewById(R.id.info_distance);
			viewHolder.infoZan = (TextView) mMarkerLy
					.findViewById(R.id.info_zan);

			mMarkerLy.setTag(viewHolder);
		}
		viewHolder = (ViewHolder) mMarkerLy.getTag();
		viewHolder.infoImg.setImageResource(info.getImgId());
		viewHolder.infoDistance.setText(info.getDistance());
		viewHolder.infoName.setText(info.getName());
		viewHolder.infoZan.setText(info.getZan() + "");
	}

这里我们使用了一个ViewHoler进行控件的复用,让findViewById仅仅会运行一次

	/**
	 * 复用弹出面板mMarkerLy的控件
	 * 
	 * @author zhy
	 * 
	 */
	private class ViewHolder
	{
		ImageView infoImg;
		TextView infoName;
		TextView infoDistance;
		TextView infoZan;
	}

最后加入地图的单击事件,隐藏出现的具体信息布局和InfoWindow

mBaiduMap.setOnMapClickListener(new OnMapClickListener()
		{

			@Override
			public boolean onMapPoiClick(MapPoi arg0)
			{
				return false;
			}

			@Override
			public void onMapClick(LatLng arg0)
			{
				mMarkerInfoLy.setVisibility(View.GONE);
				mBaiduMap.hideInfoWindow();

			}
		});

最后看一下我们的布局文件:


除了MapView,其它都是具体信息的布局。默认是隐藏的,当用户点击Marker显示以及设置初值,当用户单击地图时再将其隐藏。


好了。到此介绍完毕~~


源代码点击下载

注:开发人员key须要换成自己申请的,不清楚申请的请看第一篇博客的。


百度地图相关博客视频版本号已经上线:Android中百度地图的使用期待您的支持。


博主部分视频已经上线,假设你不喜欢枯燥的文本。请猛戳(初录。期待您的支持):

1、Android 自己定义控件实战 电商活动中的刮刮卡

2、Android自己定义控件实战  打造Android流式布局和热门标签

3、Android智能机器人“小慕”的实现

4、高仿QQ5.0側滑

5、高仿微信5.2.1主界面及消息提醒



百度地图相关博客视频版本号已经上线:Android中百度地图的使用期待您的支持。



博主部分视频已经上线,假设你不喜欢枯燥的文本。请猛戳(初录,期待您的支持):

1、Android 自己定义控件实战 电商活动中的刮刮卡

2、Android自己定义控件实战  打造Android流式布局和热门标签

3、Android智能机器人“小慕”的实现

4、高仿QQ5.0側滑

5、高仿微信5.2.1主界面和消息提醒


版权声明:本文博客原创文章。博客,未经同意,不得转载。