Android5.xSVG矢量动画机制

        Google在Android5.x中增加了对SVG矢量图形的支持,这对于创建新的高效率动画具有非常重大的意义。首先,来了解下什么时SVG。

  • 可伸缩矢量图形(Scalable Vector Graphics)
  • 定义用于网络的基于矢量的图形
  • 使用XML格式定义图形
  • 图形在放大或者改变尺寸的情况下其图形质量不会有所损失
  • 万维网联盟的标准
  • 与诸如DOM和XSL之类的W3C标准时一个整体

        SVG在Web上的应用非常广泛,在Android5.x之前的Android版本上,大家可以通过一些第三方开源库在Android中使用SVG。而在Android5.X之后,Android中添加了对SVG的标签的支持。从而让开发者可以使用SVG来创建更加丰富的动画效果。那么SCG对比传统的Bitmap,究竟有什么好处呢?Bitmap(位图)通过每个像素点上存储色彩信息来表达图像,而SVG是一个绘图标准。与Bitmap相对比,SVG最大的优点就是放大不会失真。而且Bitmap需要为不同分辨率设计多套图标。

        在讲解如何在Android5.x中使用SVG之前,我们先来了解下SVG中标签。

1.标签

        使用标签创建SVG,就像用指令的方式来控制一只画笔,例如移动画笔到某一坐标位置,画一条线,画一条曲线,结束。标签所支持的指令有以下几种。

  • M=moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制
  • L=lineto(L X,Y):画直线到指定的坐标位置
  • H=horizontal lineto(H x):画水平线到指定的X坐标位置
  • V=vertical lineto(V Y):画直线到指定的Y坐标位置
  • C=curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝塞尔曲线
  • S=smooth curveto(S X2,Y2,ENDX,ENDY):三次贝塞尔曲线
  • Q=quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝塞尔曲线
  • T=smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路径后的终点
  • A=elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
  • Z=closepath():关闭路径

        在使用上面的指令时,需要注意以下几点。

  • 坐标轴以(0,0)为中心,X轴水平向右,Y轴水平向下。
  • 所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系。
  • 指令和数据间的空格可以省略。
  • 同一指令出现多次可以只用一个。

        下面来具体看看SVG指令的使用方法。

2. SVG常用指令

  • L

        绘制直线的指令时“L”,代表从当前点绘制直线到给定点。“L”之后的参数时一个点坐标,如“L 200 400”绘制直线。同时,还可以使用“H”和"V"指令来绘制水平、竖直线,后面的参数是x坐标(H指令)或y坐标(V指令)。

  • M

        M指令类型Android绘图中path类的moveTo方法,即代表将画笔移动到某一点,但并不会发生绘制动作。

  • A
  1.         A指令用来绘制一段弧线,且允许弧线不闭合。可以把A命令绘制想象成是椭圆的某一段,A指令有以下七个参数。
  2.         RX,RY指所在椭圆的半轴大小
  3.         XROTATION指椭圆的X轴与水平方向顺时针方向夹角,可以想象成一个水平的椭圆绕中心点顺时针旋转XROTATION的角度。
  4.         FLAG1只有两个值,1表示大角度弧线,0为小角度弧线。
  5.         FLAG2只有两个值,确定从起点至终点的方向,1为顺时针,0为逆时针。
  6.         X,Y轴为终点坐标。

        SVG的指令参数非常复杂,但是在Android中,不需要绘制太多太复杂的SVG图形,在后面的学习中,读者将慢慢掌握SVG的绘制技巧和方法。

3.SVG编辑器

        SVG参数的写法固定而复杂,因此完全可以使用程序来实现,所以一般通过SVG编辑器来编辑SVG图形。网上有很多SVG的在线编辑器,通过可视化编辑好图形后,点击View Source就可以转换为SVG代码,如下图所示,网址如下所示。

        SVG在线编辑器网址

Android5.xSVG矢量动画机制_第1张图片

        下载离线的SVG编辑器,可以获得更为强大的编辑功能,例如常用的Inkscape,就是一个非常优秀的离线SVG编辑器。

4.Android中使用SVG

        Google在Android5.X中提供了下面两个新的API来帮助支持SVG:

  • VectorDrawable
  • AnimatedVectorDrawable

        其中,VectorDrawable让你可以创建基于XML的SVG图形,并结合AnimatedVectorDrawable来实现动画效果。

4.1VectorDrawable

        在XML中创建一个静态的SVG图形,通常会形成如下图所示的树形结构。

Android5.xSVG矢量动画机制_第2张图片

        下面我们来具体看看如何在XML中创建SVG图形。首先需要在XML中通过标签来声明对SVG的使用,代码如下所示。



        其中包含两组宽高属性,height、width和viewportHeight、viewportWidth。这两组属性分别具有不同的含义,height、width表示该SVG图形的具体大小,而viewportHeight、viewportWidth表示SVG图形划分的比例。后面在绘制path时所使用的参数,就是根据这两个值来进行转换的,比如上面的代码,将200dp划分为100份,如果在绘制图形时使用坐标(50,50),则意味着该坐标位于该SVG图形正中间。因此,height、width的比例与viewportHeight、viewportWidth的比例,必须保持一致,不然图形就会发生压缩、形变。

        接下来,给标签增加path,代码如下所示。



    
        
    

        通过添加标签和标签来绘制一个SVG图形,其中pathData就是绘制SVG图形所用到的指令。在这个例子中,先使用"M"指令,将画笔移动到(25,50)这个坐标,再通过A指令来绘制一个圆弧并填充。由于A命令使用非常广泛而且功能强大,所以这里读者需要仔细对照前文中A指令的参数,来掌握该命令。

        通过以上的代码,绘制一个SVG图形,图下图所示。

        Android5.xSVG矢量动画机制_第3张图片

        由于这里使用了android:fillColor属性来绘制图形,因此绘制出来的是一个填充的图形,如果要绘制一个非填充的图形,可以使用以下属性。

            android:strokeColor="#ff00ff"
            android:strokeWidth="2"

        绘制效果如下图所示。

        Android5.xSVG矢量动画机制_第4张图片

4.2 AnimatedVectorDrawable

        AnimatedVectorDrawable的作用就是给VectorDrawable提供动画效果。Google的工程师将AnimatedVectorDrawable比喻为一个胶水,通过AnimatedVectorDrawable来连接静态的VectorDrawable和动态的objectAnimator。

        下面来看看如何使用AnimatedVectorDrawable实现SVG图形的动画效果。首先,再XML文件中通过标签来声明对AnimatedVectorDrawable的使用,并指定其作用的path或group。



    

        对应的vector即为静态的VectorDrawable。



    
        
    

        需要注意的是,AnimatedVectorDrawable中指定的targer的name属性,必须与VectorDrawable中需要作用的name属性保持一致,这样系统才能找到要实现动画的元素。最后,通过AnimatedVectorDrawable中的target的animation属性,将一个动画作用到了对象name的元素上,objectAnimator代码如下。



        最后可以看到,对动画效果的实现,还是通过属性动画来实现,只是属性稍有不同。

        在标签和标签中添加了rotation、fillColor、pathData等属性,那么在objectAnimator中,就可以通过指定android:propertyName="XXXX"属性来选择控制哪一种属性,通过android:valueFrom=“XXX”和android:valueTo="XXX"属性,可以控制动画的起始值。唯一需要注意的是,如果指定属性为pathData,那么需要添加一个属性——android:valueType来告诉系统进行pathData变换。类似的情况,可以使用rotation进行旋转动画,使用fillColor实现颜色动画,使用pathData实现进行形状、位置的变化。

        当所以的XML文件准备好之后,就可以在代码中控制SVG动画,可以很方便地将一个AnimatedVectorDrawable XML文件给一个ImageView作为背景显示。

    

       在程序中,只需要使用以下代码,既可以开始SVG动画。

    ((Animatable)iv.getDrawable()).start();

      在初步了解如何使用SVG动画后,我们来看几个实例,向大家展示SVG动画的强大之处。

6. SVG动画实例

6.1线图动画

        在Android5.x中,Google大量引入了线图动画。当页面发生改变时,页面上的icon不再生硬地切换,而是通过非常生动的动画效果,转换成另一种形态。如下图所示。

Android5.xSVG矢量动画机制_第5张图片

        实例程序在运行的初始状态如下图所示。

Android5.xSVG矢量动画机制_第6张图片
        当点击图像时,开始SVG动画,上线两根线条会从中间折断并向中间折起,最终形成一个"X"。效果如下图所示。

Android5.xSVG矢量动画机制_第7张图片
        要实现这样的一个效果,首先需要创建一个静态的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();
            }
        });

6.2 模拟三球仪

        三球仪是天文学中一个星象仪器,用来模拟地、月、日三个形体的绕行轨迹,即地球绕太阳旋转,月球绕地球旋转的同时,绕太阳旋转。如下图所示。

Android5.xSVG矢量动画机制_第8张图片
         当然,这里不会完全精确地模拟这个模型,只是通过这个例子来让读者掌握SVG动画的使用技巧。

        首先,同样是需要绘制一个静态的第、月、日三星系统。

 



    
        
        
            
            
                
            
        
    

        静态效果图如下所示。

        Android5.xSVG矢量动画机制_第9张图片
              
        可以从代码中看出,在“sun”这个group中,有一个“earth"group,同时使用android:pivotX和android:pivotY属性来设置其旋转中心。这个VectorDrawable分别代表了太阳系和地月系系统。下面对这两个group分别进行SVG动画,“sun”的动画代码如下所示。



        ”earth“的动画试下代码如下。



        这里为了简化示例,我们让两个动画效果的实现完全相同。

        最后,使用黏合剂AnimatedVectorDrawable黏合SVG静态图形和动画。



    
    

        启动动画的方法与之前的实例相同,这里不再赘述。通过给group设置SVG动画,模拟了地月日三球仪,运行效果如图所示。

        Android5.xSVG矢量动画机制_第10张图片

3.轨迹动画

        Android对SVG的支持还给我们带来了很多好玩的特效,例如可以将propertyName指定为timePathStarters,这个属性用来控制一个SVG Path的显示比例,例如一个圆形的SVG,使用timePathStarters动画,可以像画出一个圆一样来绘制一个圆,从而形成一个轨迹动画效果。下面这个实例就展示了绘制轨迹的动画效果,用来绘制搜索框中的一个放大镜。如下图所示。

Android5.xSVG矢量动画机制_第11张图片
        当点击时,放大镜将按照轨迹逐渐消失。首先需要用SVG绘制一个搜索栏,代码如下所示。 




    
    


        这个SVG图像与前面两个实例类似,只是组合的图形稍微多了点。下面我们来实现动画效果,还是利用属性动画,只是将propertyName改为trimPathStart,这个属性就是利用0到1的百分比来按照绘制轨迹绘制SVG图像。类似的,还有trimPathEnd这个属性,实现代码入下.



        最后,就是我们的黏合剂——AnimatedVectorDrawable黏合动画和SVG。



    

        在代码中同样时使用前面例子的方法来启动动画,这里不再多说。使用这个方法我们就能非常高效地完成一些在之前版本中实现起来非常复杂或者效率很低地动画特效了。

你可能感兴趣的:(android群英传笔记)