看过之前那篇介绍静态 SVG 矢量图片的童鞋,应该时有感触的,SVG 就是给我们一个 空的不限制大小的canvas画板,然后我们使用 path 路径去绘制我们需要的图形,这就是静态的 SVG。动态 SVG 就是对静态 SVG 的一种扩展,就是给静态 SVG 加一个可以执行动画操作的壳。
说的简单点就是这么回事,对于兼容性来说,你只要完成了前面静态 SVG 的兼容,那么这里就不用再做其他操作了。
废话不多说,直接然我们来看看如何写动态 SVG
先上效果图:这个大家看着是不是很熟悉啊,这就是那个切换抽屉的交互。使用矢量动画来实现其实很简单,就是用了一个 pathData 的变换+旋转。这里例子 地址
这是本文中学习 项目地址 就是下面这张图
看到没这几个都是使用动态 SVG,俗称矢量动画实现的,代码很简单,原理也是很简单。
从实现上看是给静态 SVG矢量图 VectorDrawable 添加一个壳 Animated-Vector,这里壳里面绑定了 SVG 矢量图和 objectAnimator 的关系。对你没看错就是objectAnimator属性动画。
因此还有一种说法就是使用 objectAnimator属性动画对 SVG 矢量图的 path 属性进行渐变操作,就成动画啦。
好了,现在我们一一来看一下:
SVG 静态矢量图
Animated-Vector 捆绑静态矢量图和动画的壳
最上面的 drawable 属性是声明使用哪张矢量图,下面的 target 就是具体的捆绑关系了。 target 里面的name 属性是说动画时对应静态矢量图中的哪个部分,我们在画矢量图时是可以声明 group 便签的,这个就是为了后面的做动画准备的。这个 group 标签是给图片中的某以部分图像打个标记,然后我们在外层可以给这个标记的图片部分绑定一个动画。animator 就是具体的动画了,当然这些动画都只能围绕path 来做。
objectAnimtor 具体的动画
这当然还没完,这只能显示出静态 SVG 在屏幕上,要让我们的动画动起来还是要执行代码的
public void anim(View view) {
ImageView imageView = (ImageView) view;
Drawable drawable = imageView.getDrawable();
if (drawable instanceof Animatable) {
((Animatable) drawable).start();
}
}
好了这样一个动画 SVG 图片就好了,在我们不执行代码时他就是一张静态 SVG 图,我们开始执行代码后就可以跑我们设计的动画了。
这里我要感慨一些,SVG 这东西太好用了,尤其是对于 app 中我们点击 icon 后做简单的动画来实现好看的交互这点来说,简直就是绝配啊,而且可以自由创作。SVG 我们在绘制path 时可以分块,然后我们可以给按 path 块设计不筒的动画,这样是不是很简单很灵活,一个 imageview 搞定。
好了来小小的总结下,每个Vector动画,基本都包含四部分内容,即:
Vector:图像资源
Animated-vector:动画、图像粘合剂
ObjectAnimator:动画资源
代码:启动动画
每个Vector动画通过这四个部分去进行分析,就非常清晰了。
上面我们使用的trim path 的方式(剪切路径),对path做动画有3种:
- trimPath 剪切路径
- 通常的位移,旋转,缩放,渐变
- morphPath 变换路径
我们来挨个看一下这几个动画,这涉及到svg 动画的兼容
trimPath 剪切路径动画:
剪切路径动画是使用的属性动画中的 trimPathStart/trimPathEnd 来实现的
通常的位移,旋转,缩放,渐变动画
morphPath 变换路径动画
变换路径操作的是属性动画中的 pathData 来实现的
好了这3种对 path 做动画的方式我们都看过了,这里我要说一下,兼容这东西都是不完善的,所以呢在5.0以下morphPath 变换路径动画是不能使用的,写了直接报错。在5.0以上版本这个morphPath 变换路径动画可以使用,要是你在 xml 文件里对 imageview 设置 src 属性来指定动态SVG 图片,可以显示,但不会执行,这时系统的问题,你得手动用代码设置 src 属性才行
ImageView imageView = (ImageView) view;
AnimatedVectorDrawable morphing = (AnimatedVectorDrawable) getDrawable(R.id.xxx);
imageView.setImageDrawable(morphing);
if (morphing != null) {
morphing.start();
}
这样才行,手写代码设置图片呗,这是因为我们使用 AppCompatActivity后,会自动把 AnimatedVectorDrawable 转换成 AnimatedVectorDrawableCompat ,后者是不支持 pathDatad属性的,所以得自己手写代码。
其它非常奇怪、诡异、不能理解的兼容性问题,只能通过版本文件夹的方式来进行兼容了,例如drawable-v21和drawable,分别创建两个文件名相同的资源在两个文件夹下,这样在21以上版本,会使用drawable-v21的资源,而其它会使用drawable下的资源。
参考资料:
- Android中使用SVG
- Android高级动画(2)