地图显示用户头像

来源:互联网 发布:淘宝电子商务运营 编辑:程序博客网 时间:2024/05/21 14:01

最近参加小挑战杯,我们队的产品也地图有关,其中有个需求就是在地图上显示当前发布任务的用户的头像,而且头像圆形显示,咋一看,没啥太多难度,可其中遇到各种问题,多线程同步,异步加载,自定义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>() {@Overridepublic 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() {@Overridepublic void onLoadingStarted(String arg0, View arg1) {}@Overridepublic void onLoadingFailed(String arg0, View arg1,FailReason arg2) {}@Overridepublic void onLoadingComplete(String arg0, View arg1,Bitmap arg2) {bitmap=arg2;}@Overridepublic 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() {@Overridepublic 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线程跑的太快了,等等imageloadertry {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来承载所有的头像,最后导致地图上所有头像都相同。想看源代码的话私聊我吧,因为软件还没完工。


每天记录成长一点一滴



1 0
原创粉丝点击