Android 路径动画

本文译自 http://www.curious-creature.com/2013/12/21/android-recipe-4-path-tracing/

我几个月以前就已经离开了 Android 小组, 但是我依然喜欢写一些 UI 视觉效果的 Demo 给 Android 平台。目前在旅行的空闲时间里写了一些新的 Demo, 我希望能够教你们一些开发技巧。

这个新的 Demo 叫做 Road Trip USA, 展示了如何实现路径动画效果, 下面的视频展示了路径动画的效果:

路径动画的用途很广泛:可以展示一张地图, 沿途画出每个城市的边界线, 每个城市的名字, 可以作为一个加载进度条, 进度条可以在开始只描述一个起始点, 然后随着线条的绘制逐渐展现整个进度条。

为了更好的理解下文, 建议你先看看源码(https://github.com/romainguy/road-trip)或者获取APK(http://goo.gl/8eyy7o)体验一下。

路径特效

路径动画主要是靠 Android ApiPathEffect(https://developer.android.com/reference/android/graphics/PathEffect)实现.一个PathEffect 对象可以传递给 Canvas.drawPath() 的 Path 对象.目前主要的 PathEffect 类型有:

CornerPathEffect把路径连线的夹角变为圆弧夹角

DashPathEffect把路径的连线变为虚线

DiscreatePathEffect把路径变为一系列随机的,偏离原路径的片段

PathDashPathEffect使用另外一种路径作为模板来绘制当前的路径

这些类型又可以被ComposePathEffect或者SumPathEffect组合,举个例子:一个被连接在一起的线段通过使用 ComposeEffect(包含 CornetPathEffect和DashPathEffect)能够被转为圆角虚线的路径。如下图所示:

逐步退出效果

下面的进度条实例就是使用了一个PathDashPathEffect和凹进去的箭头作为模板.因为 PathEffect Api 已经帮我们做了所有的工作,我们只需要创建一个路径就可以了:

我们要实现逐步退出效果的关键是 PathDashPathEffect 的第三个参数phase (与第一个模板的偏移距离),使用动画改变这个值,就能够达到逐渐退出的效果。

路径动画

路径动画也是使用了 phase 参数, 但是现在使用的是 DashPathEffect 而不是 PathDashPathEffect。 你制定虚线的的长度, 也可以制定虚线之间的间隙, 传递给 DashPathEffect 的构造函数。只要让虚线和空隙的长度比路径本身长的话, 就能够实现路径动画。

计算一个线段的长度非常简单, 但是要计算一个随意的线段长度就有一点复杂了, 因为我们需要计算二次或者三次曲线。幸运的是 android 提供给我们一个简单的 api 来计算这种路径的长度:

运行上面这段代码你会发现几乎和不使用 PathEffect 一样, 这是因为 DashPathEffect 总是先画实线, 所以我们需要先创建一个长度和路径长度一样的空隙。

接下来我们只需要使用属性动画将 phase 的值从 0 变到 length 就可以了. 你可以在 StateView.java 里面看到整个动画的实现.

描画箭头

箭头指示器的实现要更加多一点技巧, 不再只是使用一个 PathEffect, 我们需要 2 个:一个 DashPathEffect 用来画箭头的尾部, 一个 PathDashPathEffect 用来画箭头顶部.PathDashPathEffect 的 advance 参数设置为整个箭头从顶部到尾部的路径长度。

你可以在 IntroView.java 找到整个实现。

使用 SVG 路径

在这个 demo 里面我使用 SVG 文件来存储路径信息,SVG 文件加载虽然很慢, 但是完全可以使用其他简化版二进制格式的方式来加载, 因为我们只需要路径的几何数据, 而不需要样式数据。

我选择了第三方库androidsvg(https://github.com/BigBadaboom/androidsvg), 因为它使用简单, 但是它却不能获取到 SVG 文件里面的路径信息. 所以我使用一个自定义的 Canvas, 并且复写 drawPath() 方法:

路径已经被预加载了, 所以我们能够准确的获取到路径在各种屏幕上的大小. 一个更加高级的版本你可以参考 SvgHelper.java. 这个实现增加能够让路径自动在它的容器里缩放。

其他的视觉效果

如果你仔细体验这个 Demo, 你将会注意到其他的几个视觉效果:

黑白色转换, 当把一行图片滑向左边的时候出现

固定滑动, 一种类似固定的卡片滑动效果, 当上下滑动列表的时候出现

并行滑动, 不同的项目以不同的速度滑动

动态实现标题栏透明, 和 Google Music 效果类似

这些所有的效果都可以在 MainActivity.java 里找到。

作 /Romain Guy

译 / 尚吉 @ 创宇前端

编 / 荧声 @ 创宇前端

感谢您的阅读

欢迎关注、点赞、留言讨论、分享转发支持我们

经常错过推送?

给创宇前端公众号加上星标吧

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181109G0QV6R00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券