使用 SVG 实现交互式地图
前言
说起 SVG ,大家肯定都已经使用过,但是如何更深刻的去探究 svg ,以及利用它和自定义 View 结合制作更加复杂的控件,这样才能通过不断的实践去提高自己。
如何制作呢?首先先上一个效果图。
如何实现?
SVG 的特性就是通过Path去绘制,而我们就是利用path绘制每一个省份,我们拼接成完整的地图。
- 获得地图的svg图片 https://www.amcharts.com/dl/javascript-maps/ 可以在该链接下下载世界任意一个国家地图
- svg 转化成 Vector Drawable Vector就是Android中的SVG实现(并不是支持全部的SVG语法,现已支持的完全足够用了) 利用 http://inloop.github.io/svg2android/ 转化
- 解析获得的地图中每一个PATH,分别绘制
- 交互式地图,判断触摸位置
- 地图的适配工作
实现过程
前面两步直接完成,这里不再阐述,在得到 Vector 之后,我们需要xml解析,此处利用docounmet解析。
|
|
接下来就是自定义view的知识,我们需要自定义view,在onDraw 中绘制地图,由于每一个省都要绘制,所以我们需要自定义每一个城市item ,item去完成绘制操作。代码如下:
|
|
分析:此处截取的是 onDraw 方法,每一个都单独绘制,通过对选中的城市单独绘制 ProviceItem 就是每一个省份的item,下面贴出代码
|
|
分析:ProviceItem 负责自己的绘制逻辑,同时判断当前点击是否在当前地图范围内,如果判断下文会详细阐述
对于一个不规则的图形,如果去实现点击实现?
这里在Android中通过path绘制的图形,能够在以下的方式中完成判断
这里会介绍一个类 Region 它是区域的意思,就是能截图屏幕中一块区域。如何截取?就通过 RectF 去限定一个区域,PATH能获取自己的边界, Region 通过 setPath方法,能在path限定的边界中,截取path绘制的图形的部分通过 contains方法就行判断处当前点击的位置是否在区域内。
|
|
到此处基本上就能完成可交互地图的编写,完成地图的逻辑,难点都在此处阐述。完整的代码会在文章最后给出。
接下来就是适配工作,如果去让地图能放缩?我们不仅仅需要获取控件本身的宽高,还要知道svg图片的大小,如何得到地图的大小?而地图的大小是每一个path组成的,就是说我们只能知道每一个path的大小,但是不能得到整个地图的大小,这里我们的解决办法是去遍历path,取四个方向path的最值,这样得到的边界就是地图本身的大小。
|
|
在 onMeasure完成mapview的测量 默认高度,获得参考高度,这样不会造成宽高比例失调的情况
|
|
利用控件宽高和图片本身大小实现完美放缩
|
|
控件的宽高设置,决定放缩比例,而放缩比例在 onDraw方法中完成对canvas的放缩,从而实现适配
小结:
利用SVG绘制可交互式地图,回想看看,整个过程其实同样可以使用自定义View的开发,只要能有和原型图一样的SVG图片,我们利用这个方式就能完成自定义View,以后自定义View只要找UI要SVG图片就行了,哈哈。
最后附上代码链接 https://github.com/kehanchenk/workproject
结语
工作原因,也有自己的原因好久没更新博客,此次带来关于中国地图的svg的自定义view,希望能给我提出文章的不足或者漏洞,以此共勉!