使用SVG打造可交互的自定义地图
来源:互联网 发布:梧桐一叶落而天下知秋 编辑:程序博客网 时间:2024/06/04 20:03
最近发现了一个好玩的东西:SVG,秉承着学以致用的原则,做了一个小demo。
先上效果图:
这是一个可以交互的中国地图.
像这类复杂的自定义空间,如果要我们自己来画,我估计会让我开始怀疑人生吧!
好了 废话不多说,下面我们就用svg的方式来实现这个自定义的地图控件:
步骤:
1:下载中国地图的svg文件
2:然后将svg文件转换成android能用的xml文件:附上链接一个:http://inloop.github.io/svg2android/
3:由于步骤2解析到的SVG是xml格式的,如果说不做交互的话,可以直接显示(可改变源文件的颜色),如果要做交互的话,就需要获取到每一个省对应的path,然后设置交互点击事件了,这样的话,就需要解析得到我们需要的path。
4:解析完之后,就需要将每一个path会知道canvas中去
5:设置点击事件,判断当前点击的是哪个省份
这里1,2步就直接略过了,我们从第三步开始:
//开启一个线程,用于解析xml文件private Thread parseSvgThread = new Thread(new Runnable() { @Override public void run() { InputStream inputStream = mContext.getResources().openRawResource(R.raw.china); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); Document doc = builder.parse(inputStream); Element rootElements = doc.getDocumentElement(); //解析path节点 NodeList items = rootElements.getElementsByTagName("path"); for(int i = 0;i<items.getLength();i++){ Element element = (Element) items.item(i); String pathData = element.getAttribute("android:pathData"); Path path = PathParser.createPathFromPathData(pathData); //将解析的每一条path创建一个javabean,然后放到容器中 Province province = new Province(path); itemLists.add(province); } //解析完成之后,发送handler 通知解析完成并设置颜色 mHandler.sendEmptyMessage(0); } catch (Exception e) { e.printStackTrace(); } } }); Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if(itemLists != null && itemLists.size() > 0){ int size = itemLists.size(); for(int i = 0;i<size;i++){ //简单设置下颜色itemLists.get(i).setDrawColor(colors[i%colors.length]); } //更新绘制 invalidate(); } } };
由于解析过程比较耗时,所以我们开启一个独立的线程来解析,解析完成之后通过handler来设置每一个省的颜色,然后更新绘制
第四步:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //1:画选择的 //2画没别选择的 if(itemLists != null && itemLists.size()>0){ canvas.save(); canvas.scale(scale,scale); if(mSelectedItem != null){ mSelectedItem.drawableProvince(mPaint,canvas,true); } for(int i = 0;i<itemLists.size();i++){ if(itemLists.get(i) != mSelectedItem){ itemLists.get(i).drawableProvince(mPaint,canvas,false); } } canvas.restore(); } }
然后在province的bean中,我们来做绘画的操作:
//在画板上画 public void drawableProvince(Paint paint, Canvas canvas,boolean isSelected){ if(isSelected){ //当前被选择的省 //画阴影 paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(2); paint.setColor(Color.BLACK); paint.setShadowLayer(8,0,0,0xffffff); canvas.drawPath(path,paint); //画填充部分 paint.clearShadowLayer(); paint.setColor(Color.RED); canvas.drawPath(path,paint); }else{ //画填充部分 paint.setColor(drawColor); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(1); canvas.drawPath(path,paint); paint.setStyle(Paint.Style.STROKE); paint.setColor(0xFFD0E8F4); canvas.drawPath(path,paint); } }
到这里,地图就可以按照我们自定义的颜色来显示了。
最后一步,设置监听,首先,我们在prvoince这个bean中,写一个方法,来判断当前点击的这个点是否在province中:
//判断某一点是否包含在该省内 public boolean isContain(int x,int y){ RectF rectF = new RectF(); path.computeBounds(rectF,true); Region region = new Region(); region.setPath(path,new Region((int)rectF.left,(int)rectF.top,(int)rectF.right,(int) rectF.bottom)); return region.contains(x,y); }
这里使用的方法是:创建一个包含path的区域(region),然后使用region的contains方法来进行判断。
最后,我们只需要在mapview中来处理touch事件并刷新ui就可以了。
阅读全文
0 0
- 使用SVG打造可交互的自定义地图
- SVG 绘制可交互的中国地图
- 可缩放矢量图形SVG的使用
- svg交互的
- 可重用的SVG
- SVG与JS的交互
- SVG与JS的交互
- SVG的画台湾地图
- Android使用SVG矢量图打造酷炫动效!
- Android使用SVG矢量图打造酷炫动效!
- 可移植的SVG文档
- 可移植的SVG文档
- e-Chart示例之可交互地图
- 使用Consul打造弹性可扩展的PaaS平台
- 使用Consul打造弹性可扩展的PaaS平台
- 使用 ViewPager+GridView轻松打造可分页的GridView
- 可交互的AsyncTask
- [HTML5-SVG]Html5的可缩放矢量图形实例SVG
- Java网络编程面试题
- apache james用户信息的数据库存储和密码问题_邮件服务器
- 数据库引擎
- 简单逻辑电路的设计
- 【python学习记录】-3-Python图像处理库:Pillow 初级教程
- 使用SVG打造可交互的自定义地图
- 测试手机闪存读写速度
- HDU 1727 Hastiness(模拟)
- hdoj 2844 Coins(多重背包)
- Oracle数据库的表空间
- 7.C语言(5)
- 分别显示用float和double指数记数法所能表示的最大值和最小值 以一个最高有效位为1的二进制数字开始,用有符号右移操作符对其进行右移,直至所有二进制位都被移除为止,每移一位都要使用Integer
- Handler图片自动轮播
- JAVA-"abstract"与"接口(interface)"