Google在Android5.x中增加了对SVG矢量图形的支持,这对于创建新的高效率动画具有非常重大的意义。首先,来了解下什么时SVG。
SVG在Web上的应用非常广泛,在Android5.x之前的Android版本上,大家可以通过一些第三方开源库在Android中使用SVG。而在Android5.X之后,Android中添加了对SVG的
在讲解如何在Android5.x中使用SVG之前,我们先来了解下SVG中
使用
在使用上面的指令时,需要注意以下几点。
下面来具体看看SVG指令的使用方法。
绘制直线的指令时“L”,代表从当前点绘制直线到给定点。“L”之后的参数时一个点坐标,如“L 200 400”绘制直线。同时,还可以使用“H”和"V"指令来绘制水平、竖直线,后面的参数是x坐标(H指令)或y坐标(V指令)。
M指令类型Android绘图中path类的moveTo方法,即代表将画笔移动到某一点,但并不会发生绘制动作。
SVG的指令参数非常复杂,但是在Android中,不需要绘制太多太复杂的SVG图形,在后面的学习中,读者将慢慢掌握SVG的绘制技巧和方法。
SVG参数的写法固定而复杂,因此完全可以使用程序来实现,所以一般通过SVG编辑器来编辑SVG图形。网上有很多SVG的在线编辑器,通过可视化编辑好图形后,点击View Source就可以转换为SVG代码,如下图所示,网址如下所示。
SVG在线编辑器网址
下载离线的SVG编辑器,可以获得更为强大的编辑功能,例如常用的Inkscape,就是一个非常优秀的离线SVG编辑器。
Google在Android5.X中提供了下面两个新的API来帮助支持SVG:
其中,VectorDrawable让你可以创建基于XML的SVG图形,并结合AnimatedVectorDrawable来实现动画效果。
在XML中创建一个静态的SVG图形,通常会形成如下图所示的树形结构。
下面我们来具体看看如何在XML中创建SVG图形。首先需要在XML中通过
其中包含两组宽高属性,height、width和viewportHeight、viewportWidth。这两组属性分别具有不同的含义,height、width表示该SVG图形的具体大小,而viewportHeight、viewportWidth表示SVG图形划分的比例。后面在绘制path时所使用的参数,就是根据这两个值来进行转换的,比如上面的代码,将200dp划分为100份,如果在绘制图形时使用坐标(50,50),则意味着该坐标位于该SVG图形正中间。因此,height、width的比例与viewportHeight、viewportWidth的比例,必须保持一致,不然图形就会发生压缩、形变。
接下来,给
通过添加
通过以上的代码,绘制一个SVG图形,图下图所示。
由于这里使用了android:fillColor属性来绘制图形,因此绘制出来的是一个填充的图形,如果要绘制一个非填充的图形,可以使用以下属性。
android:strokeColor="#ff00ff"
android:strokeWidth="2"
绘制效果如下图所示。
AnimatedVectorDrawable的作用就是给VectorDrawable提供动画效果。Google的工程师将AnimatedVectorDrawable比喻为一个胶水,通过AnimatedVectorDrawable来连接静态的VectorDrawable和动态的objectAnimator。
下面来看看如何使用AnimatedVectorDrawable实现SVG图形的动画效果。首先,再XML文件中通过
对应的vector即为静态的VectorDrawable。
需要注意的是,AnimatedVectorDrawable中指定的targer的name属性,必须与VectorDrawable中需要作用的name属性保持一致,这样系统才能找到要实现动画的元素。最后,通过AnimatedVectorDrawable中的target的animation属性,将一个动画作用到了对象name的元素上,objectAnimator代码如下。
最后可以看到,对动画效果的实现,还是通过属性动画来实现,只是属性稍有不同。
在
当所以的XML文件准备好之后,就可以在代码中控制SVG动画,可以很方便地将一个AnimatedVectorDrawable XML文件给一个ImageView作为背景显示。
在程序中,只需要使用以下代码,既可以开始SVG动画。
((Animatable)iv.getDrawable()).start();
在初步了解如何使用SVG动画后,我们来看几个实例,向大家展示SVG动画的强大之处。
在Android5.x中,Google大量引入了线图动画。当页面发生改变时,页面上的icon不再生硬地切换,而是通过非常生动的动画效果,转换成另一种形态。如下图所示。
实例程序在运行的初始状态如下图所示。
当点击图像时,开始SVG动画,上线两根线条会从中间折断并向中间折起,最终形成一个"X"。效果如下图所示。
要实现这样的一个效果,首先需要创建一个静态的SVG图形,即静态的VectorDrawable,并绘制为初始状态。
path1和path2分别绘制了两条直线,每条直线由三个点控制,即起点和中点,形成初始状态 。接下来实现变换objectAnimator动画。下面是动画1.
android:valueFrom="M 20 20 L 50 20 80 20"
android:valueTo="M 20 20 L 50 50 80 20"
android:valueType="pathType" android:interpolator="@android:anim/bounce_interpolator">
在以上代码中,定义了一个pathType的属性动画,并指定了变换的起始值分别为:
android:valueFrom="M 20 20 L 50 20 80 20"
android:valueTo="M 20 20 L 50 50 80 20"
这两个值,即对应其实状态值。不过这里需要注意的时,SVG的路径变换属性动画中,变换前后的节点数必须相同,这也是为什么前面需要使用三个点来绘制一条直线的原因,因为后面需要中点进行动画变换。
动画2的代码如下所示。
有了VectorDrawable和objectAnimator,剩下的只需要使用AnimatedVectorDrawable来将它们黏合在一起即可。
针对trick这样一个VectorDrawable中的path1和path2两个动作路径,分别使用了objectAnimator的anim_path_example1_1和anim_path_example1_2,让这两个path实现了动画效果。最后只要在代码中启动动画属性即可。
final ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((Animatable)iv.getDrawable()).start();
}
});
三球仪是天文学中一个星象仪器,用来模拟地、月、日三个形体的绕行轨迹,即地球绕太阳旋转,月球绕地球旋转的同时,绕太阳旋转。如下图所示。
当然,这里不会完全精确地模拟这个模型,只是通过这个例子来让读者掌握SVG动画的使用技巧。
首先,同样是需要绘制一个静态的第、月、日三星系统。
静态效果图如下所示。
可以从代码中看出,在“sun”这个group中,有一个“earth"group,同时使用android:pivotX和android:pivotY属性来设置其旋转中心。这个VectorDrawable分别代表了太阳系和地月系系统。下面对这两个group分别进行SVG动画,“sun”的动画代码如下所示。
”earth“的动画试下代码如下。
这里为了简化示例,我们让两个动画效果的实现完全相同。
最后,使用黏合剂AnimatedVectorDrawable黏合SVG静态图形和动画。
启动动画的方法与之前的实例相同,这里不再赘述。通过给group设置SVG动画,模拟了地月日三球仪,运行效果如图所示。
Android对SVG的支持还给我们带来了很多好玩的特效,例如可以将propertyName指定为timePathStarters,这个属性用来控制一个SVG Path的显示比例,例如一个圆形的SVG,使用timePathStarters动画,可以像画出一个圆一样来绘制一个圆,从而形成一个轨迹动画效果。下面这个实例就展示了绘制轨迹的动画效果,用来绘制搜索框中的一个放大镜。如下图所示。
当点击时,放大镜将按照轨迹逐渐消失。首先需要用SVG绘制一个搜索栏,代码如下所示。
这个SVG图像与前面两个实例类似,只是组合的图形稍微多了点。下面我们来实现动画效果,还是利用属性动画,只是将propertyName改为trimPathStart,这个属性就是利用0到1的百分比来按照绘制轨迹绘制SVG图像。类似的,还有trimPathEnd这个属性,实现代码入下.
最后,就是我们的黏合剂——AnimatedVectorDrawable黏合动画和SVG。
在代码中同样时使用前面例子的方法来启动动画,这里不再多说。使用这个方法我们就能非常高效地完成一些在之前版本中实现起来非常复杂或者效率很低地动画特效了。