地图显示用户头像

最近参加小挑战杯,我们队的产品也地图有关,其中有个需求就是在地图上显示当前发布任务的用户的头像,而且头像圆形显示,咋一看,没啥太多难度,可其中遇到各种问题,多线程同步,异步加载,自定义view,数据检索,垃圾自动回收机制。最后做出来时候,有点小激动。下面详细和记录我的解决方案。


首先看看效果图




首先,我用的百度地图,百度地图实现定位,添加覆盖物,周边检索,poi,路线规划都做的挺好了。可以参考百度地图开发者平台,其中在地图上添加用户头像其实就是在地图上添加覆盖物marker。我大致先顺一遍开发思路。首先从后台获取附近10km内所有任务封装在任务集合中(其中任务是个实体类),之后通过任务去后台去查询发布任务人的信息,发布人的名字,地点......其中要检索到发布人头像的url,并通过头像url,在客户端用异步加载机制ImageLoader来加载头像,ImageLoader反馈一个Bitmap头像信息。将所有头像Bitmap异步加载下来存起来,之后根据从后台获取的任务集合,来循环添加头像到地图上,其中需要坐标,覆盖物marker,具体所需参数参考百度地图demo。


<span style="font-size:18px;">static String avaterURL;
	static BitmapDescriptor bitmapDescriptor;

	/**
	 * 
	 * @param publisherName
	 *            发布人姓名
	 */
	public static void getNearbyTaskAvaters(final String publisherName) {
		AVQuery<AVObject> query = new AVQuery<AVObject>("Gender");

		query.whereEqualTo("username", publisherName);
		query.findInBackground(new FindCallback<AVObject>() {

			@Override
			public void done(List<AVObject> arg0, AVException arg1) {
				Log.e("avaterURL", "共有" + arg0.size() + "个任务");
				if (arg0 != null && arg0.size() != 0) {
					AVObject publisher = arg0.get(arg0.size() - 1);
					AVFile avaterFile = publisher.getAVFile("avater");
					avaterURL = avaterFile.getUrl();
					Message msg = Message.obtain();
					Log.e("avaterURL", avaterURL + "");
					msg.obj = avaterURL;
					msg.what = 2;
					handler.sendMessage(msg);
					// bitmapDescriptor=load();
					// Log.e("avaterURL", "load完了");
				}
			}
		});

	}

	private static Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 1:
				bitmapDescriptor = load();
				break;
			case 2:
				bitmap= loadToBitmap();
				break;
			default:
				break;
			}
		};
	};
private static Bitmap bitmap;
	public static Bitmap loadToBitmap() {
		DisplayImageOptions options = new DisplayImageOptions.Builder()
				.showImageForEmptyUri(R.drawable.default_load)// 设置图片Uri为空或是错误的时候显示的图片
				.showImageOnFail(R.drawable.default_load)// 设置图片加载或解码过程中发生错误显示的图片
				.bitmapConfig(Bitmap.Config.RGB_565).build();
		ImageLoader.getInstance().loadImage(avaterURL, options,
				new ImageLoadingListener() {

					@Override
					public void onLoadingStarted(String arg0, View arg1) {

					}

					@Override
					public void onLoadingFailed(String arg0, View arg1,
							FailReason arg2) {

					}

					@Override
					public void onLoadingComplete(String arg0, View arg1,
							Bitmap arg2) {
						bitmap=arg2;
						
					}

					@Override
					public void onLoadingCancelled(String arg0, View arg1) {

					}
				});

		return bitmap;
	}
	public static Bitmap getBitmap(){
		return bitmap;
	}
	public static BitmapDescriptor getBitmapDescriper() {
		Log.e("bitmapDescriptor", bitmapDescriptor + "");
		return bitmapDescriptor;

	}</span>


上面代码实现了从后台获取头像,以bitmap来返回,其中用到了开源异步加载库,ImageLoader,使用前需要配置,不清楚的请自行百度



<span style="font-size:18px;">/**
	 * 查找附近的服务
	 */
	public void findTaskNearBy() {
		taskNearBy.clear();
		// initMarker();
		new Thread(new Runnable() {

			@Override
			public void run() {
				AVQuery<AVObject> query = new AVQuery<>("Task");
				// 查找附近10km内的任务
				query.whereWithinKilometers("geoPoint", mMyPoint, 10);
				// query.whereNotEqualTo("publisherName", mUsername);
				try {
					List<AVObject> taskList = query.find();
					Task taskBean = null;
					for (AVObject task : taskList) {
						taskBean = new Task();
						taskBean.setPublisherName(task
								.getString("publisherName"));
						taskBean.setAccepted(false);
						taskBean.setAccomplished(false);
						taskBean.setEndTime(task.getString("endTime"));
						taskBean.setPrice(task.getString("price"));
						taskBean.setTheme(task.getString("theme"));
						taskBean.setTaskDescription(task
								.getString("TaskDescription"));
						taskBean.setType(task.getString("service_task"));
						taskBean.setLatitude(task.getAVGeoPoint("geoPoint")
								.getLatitude());
						taskBean.setLongitude(task.getAVGeoPoint("geoPoint")
								.getLongitude());
						taskBean.setLocation(task.getString("location"));
						taskBean.setType(task.getString("service_type"));
						taskNearBy.add(taskBean);
					}
//					mHandler.obtainMessage(1).sendToTarget();
					loadAllAvaters();
					Log.e("task", taskNearBy.size() + "");
					Log.e("task", taskNearBy.toString());
				} catch (AVException e) {
					e.printStackTrace();
				}
			}
		}).start();
		Log.e("ShowNearMenMapActivity", "findTaskNearBy被执行");

	}</span>

以上代码实现从数据库检索附近所有任务,封装到一个集合中


<span style="font-size:18px;">/**
	 * 异步加载所有的头像
	 */
	public void loadAllAvaters(){
		for(int i=0;i<taskNearBy.size();i++){
			AVService.getNearbyTaskAvaters(taskNearBy.get(i).getPublisherName());
			
			//主线程跑的太快,让他等子线程异步加载完头像信息,不然获取的头像都为空
			//sb线程跑的太快了,等等imageloader
			try {
				Thread.sleep(600);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Bitmap bitmap= AVService.getBitmap();
			if(bitmap!=null){
				bitMaps.put(taskNearBy.get(i).getPublisherName(),
						bitmap);
			}
		}
		Log.e("avaterMarkers", avaterMarkers.size()+"\n"+avaterMarkers.toString());
		Log.e("loadAllAvaters", "方法被执行");
		
		showAllMarkersOnMap();
	}</span>

这儿就是异步加载所有头像,然后保存到一个map中,现在所有头像都存起来啦。


<span style="font-size:18px;">/**
	 * 将所有任务以发布人头像显示在地图上
	 */
	private void showAllMarkersOnMap(){
		mBaiduMap.clear();
		Marker marker = null;
		LatLng latLng = null;
		OverlayOptions options;
		for(int i=0;i<taskNearBy.size();i++){
			latLng = new LatLng(taskNearBy.get(i).getLatitude(), taskNearBy.get(i).getLongitude());
//			options = new MarkerOptions().position(latLng)
//					.icon(avaterMarkers.get(taskNearBy.get(i).getPublisherName())).zIndex(5);
			initMarker();
			Bitmap bitmap=Bitmap.createBitmap(bitMaps.get(taskNearBy.get(i).getPublisherName()));
			circleImageView.setImageBitmap(bitmap);
			circleImageView.setImageAlpha(0);
			mMarkDescriptor = BitmapDescriptorFactory
					.fromView(circleImageView);
			options = new MarkerOptions().position(latLng)
					.icon(mMarkDescriptor).zIndex(5);
			marker = (Marker) mBaiduMap.addOverlay(options);
			marker = (Marker) mBaiduMap.addOverlay(options);
			Bundle arg0 = new Bundle();
			arg0.putSerializable("info", taskNearBy.get(i));
			marker.setExtraInfo(arg0);
		}
		
		MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
		mBaiduMap.setMapStatus(msu);
	} </span>

现在最后一步,就是遍历任务,根据发布任务人的地理位置,发布人的头像,将头像显示在地图上。其中圆形头像是通过一个开源库实现,叫CircleImageview,其中circleimageview设置属性时候需要设置透明度为0,不然会出现这种效果



好了,大概的实现思路就是这样,其实一开始我不是这么实现的,我是每下载一个头像就去添加到地图上,通过一个view来承载所有的头像,最后导致地图上所有头像都相同。想看源代码的话私聊我吧,因为软件还没完工。


每天记录成长一点一滴



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值