矢量图路径问题的pathview实现方案

在前面博客关于矢量路线图动态路径在Android实现方案中,根据一些资料简单制定了一些实现方案,该文简单介绍下pathview方案的实现过程

先上图看下最终的效果

初始化 点击高亮显示指定路径后

实现思路

运行了android-pathview项目 了解到该项目实现了在svg图上进行路径绘制的效果,因此根据android-pathview项目的源码能找到实现思路。看过android-pathview 项目源码后,发现要走的路还很长。

android-pathview项目的实现思路

  • 基于androidsvg 之上,自定义Pathview模拟加载svg资源到自定义canvas,为什么叫模拟加载,其实Canvas是new出来的并没有真正渲染到视图上
  • 通过重写Canvas的drawPath方法后可以获取到的svg元素解析后的path路径(androidsvg实现)
  • 将获取到的path添加到一个list中
  • 重新绘制Pathview,(onDraw方法中遍历path绘制,之后正常绘制svg)
  • 当然其中还有一些动画方面的东西,忽略不提。

问题

思考

  • 图形缩放、移动;发现了android-pathview项目的SvgUtils rescaleCanvas方法,改方法是做svg图形的渲染,这部分作者做了canvas的移动和缩放。那么我们可以考虑在该方法加入canvas的移动缩放的外部控制,那么图的缩放移动就实现了。最终实践后确认可以
  • 绘制指定路径,实现元素点击,他们共同的一个问题就是需要svg元素和解析后的path对应。这样我通过输入svg元素的id就能找到它解析后对应的path做指定路径的绘制,通过点击path我就能知道是哪个对应的svg元素被点击了并作出相应的处理。所以对应必须实现。
  • 在点击事件中有面临的一个问题是,如何判断点击位置是哪个path呢。这个通过Region不难实现

实现

  • 关于移动部分的实现和path点击事件处理就不多说了
  • 重点说下svg元素和path的对应解决方法,为了不再花大量时间去阅读androidsvg的代码看svg到android graphics的渲染,我想到的最快的解决方案(当然不一定是好的)是按顺序去对应。经过测试果然drawPath的绘制和svg元素在文档中出现的顺序是一致的(canvas没有做特殊设置,因为不能确定canvase或对齐方式有变化时会不会有影响),那么我们是不是可以根据顺序就能确定该path对应svg的元素呢,答案是肯定的。
  • 当然不能忽略的一件事是如何顺序获取到svg的全部元素节点,通过简单浏览androidsvg代码发现了getElementsByTagName这个方法(但是它是protected方法,不得已将androidsvg源码拿了过来放到相同包下),它可以根据svg元素类型去搜索到全部该类型的SvgObject。根据我测试的svg文件,发现节点元素渲染成path的有Ellipse、Circle、Path三种,所以我按顺序对svg文件进行了整理,将相同类型元素放在一起,整体按组Ellipse-Circle-Path放置。那么就可以做到在drawPath方法中取得的svg元素和path一一对应,之后存入一个LinkedHashMap中。
  • 拿到了svg节点和path的对应,那么绘制和事件对应就没有问题了

代码实现

(https://github.com/pangff/pff-lib) 中的VectorPathView部分。 个人认为实现方式不是很好,而且要求svg规则有序,有想法的同学欢迎指正

评论

Copyright © 2022 pangff 京ICP备14050056号-1 Design credit: Shashank Mehta