点击上方蓝字关注码个蛋
一招一式,看遍天下
作者:IAM四十二
博客:http://www.jianshu.com/u/c6f7cfa366d9
文章目录
前言
效果图
地图MapView实现
地图MapView的简单显示
MapView显示到当前位置
添加View到MapView
街景地图PanoViewActivity实现
街景地图PanoView基础
将地图MapView展示在街景PanoView上面
实现对街景视图操作的监听
0
前言
使用过百度地图的同学知道,它有个街景功能,可以看到许多地方的实景。这里就其街景内容的实现,进行下学习。
在百度地图SDK的官网(http://lbsyun.baidu.com/)上可以看到,百度对开发者提供了很多相关的内容,方便我们进行学习。关于SDK的使用方法,包括jar包导入,*.so 动态库的添加位置及AndroidManifest文件的配置不做为我们这里讨论的内容,官方文档已经介绍的很详细,不做无聊的搬运工。
1
效果图
这里我们首先预览下,今天最终要实现的效果图
静态图1
静态图2
效果图
如图所示,我们这里的实现,就是两个页面的内容,一个是基础的地图MapView,一个是街景地图PanoView。接下来,就这两个页面(Activity)分别展开来说。(由于GIF图片大小限制,效果不是很理想,文章结尾有源码地址,可以自己跑一下看一下效果先)
2
地图MapView实现
地图MapView的简单显示
布局文件
Application
一般情况下,我们的应用程序都会有一个继承自Application的类,用于实现一些初始化的方法,这里可以在Application里执行一些百度地图初始化的工作,这也是官方提倡的方式。
Activity
在Activity的OnCreate方法中实现
上面这样一段简单的代码,就可以在Activity中显示出一个MapView,也就是我们最熟悉的地图页面,是不是很简单,就像我们显示一个TextView一样。
这里说明写一下,按照官方的API指导文档,使用MapView等百度地图SDK所提供的各种实现,是需要去申请相关的key的,申请的方法在官网有着详细的介绍,这里就不再粘贴复制了;很多同学在使用MapView的时候发现,程序运行后地图没有显示,显示的都是一些方格子,这往往是由于key没有申请,或申请的方式不当造成的
MapView显示到当前位置
每次打开百度地图,都会自动定位到我们当前所在的位置,或者是我们搜索某个特定的地方作为新的位置,整个地图所呈现的区域都是新位置周边的环境。这里,关于地图的定位和搜索的相关实现内容,就不展开来说,不当做此次的重点。
假设我们已通过定位(或者是搜索),定位了到了一个位置
这个位置按照新闻里常听到的说法就是,东经116.40度,北纬39.96度,位于北京市东城区旧鼓楼大街丙1号。
接下来,我们要做的就是将MapView的视图更新到我们“定位”的位置,这个位置周边的地图才是我们关心的。
这里的mBaiduMap 是一个BaiduMap的实例,通过MapView的getMap方法即可获得。我们对地图的各种操作,设置属性都是基于这个实例进行。
通过上面的代码,我们就可以将MapView的视图更新到我们所想要的位置了。
添加View到MapView
添加Marker
按照百度地图API的说法,我们添加到地图上的小图标统一称为Marker。
通过上面的实现,我们就可以将一个小图标添加到地图层,作为标记。我们日常使用地图时,所搜周边后呈现的一系列小圆点就是如此(如下图)
marker示意图
ShowInfoWindow使用
最后一步,实现显示街景缩略图的那个小弹框。
这里首先自定义一下我们要添加到地图层的View。
这里pic这个ImageView用于显示我们要展示的街景缩略图。pano_overlay是整个弹框的布局,很简单,这里就不贴代码了。
同时,我们为这个自定义View设置点击事件,方便我们跳转到PanoView街景地图页面,并且将当前位置传递过去。
由于祖国地大物博,所以街景的覆盖并非百分之百,所以说,不是每个地方都有街景可以显示,有些鸟不拉屎的地方是看不到的。那我们怎么知道什么地方有街景呢?API为我们提供了很好的检测方法
这样,我们就可以根据当前位置,先检测一下是否有街景可以显示。这里,如果当前位置有街景,我们就通过Handler通知主线程去更新UI
这里看一下,InfoWindow的说明及其构造函数
public class InfoWindow extends java.lang.Object
在地图中显示一个信息窗口,可以设置一个View作为该窗口的内容,也可以设置一个 BitmapDescriptor 作为该窗口的内容。
在Handler的handleMessage方法中,我们通过返回的url加载图片,并将自定义的弹框View显示到之前一步添加的marker偏上一点的地方(这就是InfoWindow的构造函数中-57的意义)
关于这个加载图片的URL,可以参考这里静态图API(http://lbsyun.baidu.com/index.php?title=viewstatic)。
这样,就实现了MapView页面所有的内容。通过点击InfoWindow,就可以跳转到PanoView所在的界面去查看街景地图。
接下来,我们将介绍PanoView街景地图的实现。
3
街景地图PanoViewActivity实现
街景地图PanoView基础
街景地图PanoView的显示和基础地图MapView十分相似
首先是在布局文件中定义view
在Activity的OnCreate方法中
这里同样需要的是在Application类中做一些初始化工作;对我们所使用key的有效性进行检测。
同时在Activity里也需要做一些初始化的工作,最后就是通过PanoView的setPanorama()方法实现街景的显示。
关于这里用到的setPanorama(),根据API我们可以看到
也就是说,不仅通过经纬度,而且可以通过别的方式实现街景地图的功能,甚至室内景的实现。这里我们就使用了大家最熟悉的经纬度,对于别的实现方式有兴趣的同学,可以自己去探索一下。
将地图MapView展示在街景PanoView上面
如图所示,将一个MapView显示在PanoView之上;很自然的我们会写出下面的布局方式:
这样,我们在整个PanoView的左下角定义一个60x60大小的view用于显示一个MapView。
实现对街景视图操作的监听
街景SDK为我们提供了PanoramaViewListener这个接口,可以实现对从街景视图开始绘制到完成绘制,对街景地图的操作(如点击,旋转)的监听。
这里我们重点看一下onMessage(String msgName, int msgType)这个回调方法。
这里不得不吐槽一下,官方所提供的API文档,对这个onMessage回调方法中的参数居然没有任何有价值的解释。这里的8213及12302完全是通过打印日志自己总结出的规律。
这样,我们对于不同的操作,就可以通过Handler实现不同的UI效果。我们看一下handler的实现:
这里的处理就分两种情况:
点击事件
我们仿照百度地图的样式,实现标题栏及MapView的隐藏,并添加动画,这样可以方便用户全屏更清晰的观察街景内容。
旋转事件
上面我们说过对MapView添加Marker的方法,这里就派上用场了。随着我们对PanoView的不断拖拽旋转,通过其getPanoramaHeading() 可以得到当前视角的偏航角。
在UI线程中,我们可以通过不断移除和添加Marker,并设置不同的marker的偏转角度,从而实现一种在左下方小地图上呈现我们当前视角的效果。
好了,这样就简单模仿了一下百度地图街景的部分实现功能,由于UI资源所限制,部分效果并非完全一致,这里只是学习下而已。
代码已上传至github(https://github.com/REBOOTERS/AndroidPanoramaSample)
留言有福利,具体规则请看
「帮你养成好习惯」