Android VectorDrawable与AnimatedVectorDrawable

VectorDrawable 

Android L开始提供了新的API VectorDrawable 可以使用SVG类型的资源,也就是矢量图。先来一个例子吧。

[html] view plain copy

 print?

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <vector xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:width="256dp"  
  4.     android:height="256dp"  
  5.     android:viewportHeight="32"  
  6.     android:viewportWidth="32">  
  7.   
  8.     <path  
  9.         android:fillColor="#e11c00"  
  10.         android:pathData="M20.5,9.5  
  11.                         c-1.955,0,-3.83,1.268,-4.5,3  
  12.                         c-0.67,-1.732,-2.547,-3,-4.5,-3  
  13.                         C8.957,9.5,7,11.432,7,14  
  14.                         c0,3.53,3.793,6.257,9,11.5  
  15.                         c5.207,-5.242,9,-7.97,9,-11.5  
  16.                         C25,11.432,23.043,9.5,20.5,9.5z" />  
  17. </vector>  

上面的代码绘制出来的就是这么一个图像,控制显示心形的就是上面path这个标签,一个path代表一个元素,绘制的内容是pathData下的一长串字符,里面是SVG绘制的一系列命令,提供moveTo、lineTo、close等操作。那么接下来说说这些M,c.l标签吧。

  • M: move to 移动绘制点
  • L:line to 直线
  • Z:close 闭合
  • C:cubic bezier 三次贝塞尔曲线
  • Q:quatratic bezier 二次贝塞尔曲线
  • A:ellipse 圆弧
  • M (x y) 移动到x,y
  • L (x y) 直线连到x,y,还有简化命令H(x) 水平连接、V(y)垂直连接
  • Z,没有参数,连接起点和终点
  • C(x1 y1 x2 y2 x y),控制点x1,y1 x2,y2,终点x,y
  • Q(x1 y1 x y),控制点x1,y1,终点x,y
  • A(rx ry x-axis-rotation large-arc-flag sweep-flag x y) 
    rx ry 椭圆半径 
    x-axis-rotation x轴旋转角度 
    large-arc-flag 为0时表示取小弧度,1时取大弧度 
    sweep-flag 0取逆时针方向,1取顺时针方向 
    有个图解: 

有了这些,我们可以随意的定制矢量图了,来一发,我们定义一个三角形

[html] view plain copy

 print?

  1. <vector xmlns:android="http://schemas.android.com/apk/res/android"  
  2.      android:height="64dp"  
  3.      android:width="64dp"  
  4.      android:viewportHeight="600"  
  5.      android:viewportWidth="600" >  
  6.      <group  
  7.          android:name="rotationGroup"  
  8.          android:pivotX="300.0"  
  9.          android:pivotY="300.0"  
  10.          android:rotation="45.0" >  
  11.          <path  
  12.              android:name="v"  
  13.              android:fillColor="#000000"  
  14.              android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />  
  15.      </group>  
  16.  </vector>  

我们说说这些常用标签的含义:

path 元素里面的 pathData 就是矢量图的路径数据,除此之外还可以设置其他属性。 path 元素一共包含如下属性:

  • android:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径
  • android:pathData 和 SVG 中 d 元素一样的路径信息。
  • android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径
  • android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框
  • android:strokeWidth 定义路径边框的粗细尺寸
  • android:strokeAlpha 定义路径边框的透明度
  • android:fillAlpha 定义填充路径颜色的透明度
  • android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1
  • android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1
  • android:trimPathOffset 设置路径截取的范围 Shift trim region (allows showed region to include the start and end), in the range from 0 to 1.
  • android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.
  • android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.
  • android:strokeMiterLimit 设置斜角的上限,Sets the Miter limit for a stroked path.注: 当strokeLineJoin设置为 “miter” 的时候, 绘制两条线段以锐角相交的时候,所得的斜面可能相当长。当斜面太长,就会变得不协调。strokeMiterLimit 属性为斜面的长度设置一个上限。这个属性表示斜面长度和线条长度的比值。默认是 10,意味着一个斜面的长度不应该超过线条宽度的 10 倍。如果斜面达到这个长度,它就变成斜角了。当 strokeLineJoin 为 “round” 或 “bevel” 的时候,这个属性无效。

根元素 vector 是用来定义这个矢量图的,该元素包含如下属性:

  • android:name 定义该drawable的名字
  • android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dp
  • android:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dp
  • android:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布
  • android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布
  • android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的
  • android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in
  • android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。
  • android:alpha 该图片的透明度属性

有时候我们需要对几个路径一起处理,这样就可以使用 group 元素来把多个 path 放到一起。 group 支持的属性如下:

  • android:name 定义 group 的名字
  • android:rotation 定义该 group 的路径旋转多少度
  • android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。
  • android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。
  • android:scaleX 定义 X 轴的缩放倍数
  • android:scaleY 定义 Y 轴的缩放倍数
  • android:translateX 定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的。
  • android:translateY 定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的。

通过上面的属性可以看出, group 主要是用来设置路径做动画的关键属性的。

最后, vector 还支持 clip-path 元素。定义当前绘制的剪切路径。注意,clip-path 只对当前的 group 和子 group 有效。

  • android:name 定义 clip path 的名字
  • android:pathData 和 android:pathData 的取值一样。

从上面 vector 支持的属性可以看出,功能还是比较丰富的。例如 前面提到的三角形,通过 group 可以把其旋转 90度

AnimatedVectorDrawable

我们还可以用AnimatedVectorDrawable给矢量图添加动画。AnimatedVectorDawable可以实现一些很特别的效果,对VectorDrawable里的pathData做动画,可以从一个图形渐变到另一个图形,比如Material Design里的toolbar icon;对trimPathStart、trimPathEnd做动画,可以得到图形的绘制轨迹。

AnimatedVectorDrawable类可以去创建一个矢量资源的动画。

你通常在三个XML文件中定义矢量资源的动画载体:

<vector>元素的矢量资源,在res/drawable/(文件夹)

<animated-vector>元素的矢量资源动画,在res/drawable/(文件夹)

< objectAnimator>元素的一个或多个对象动画器,在res/anim/(文件夹)

矢量资源动画能创建<group>和<path>元素属性的动画。<group>元素定义了一组路径或子组,并且<path>元素定义了要被绘制的路径。

当你想要创建动画时去定义矢量资源,使用android:name属性分配一个唯一的名字给组和路径,这样你可以从你的动画定义中查询到它们。

接下来我就以旋转的小三角为例:

然后在看一下animated-vector文件:

[html] view plain copy

 print?

  1. <span style="font-size:14px;"><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"    
  2.                  android:drawable="@drawable/vectordrawable" >    
  3.   <target    
  4.       android:name="rotationGroup"    
  5.       android:animation="@anim/rotation" />    
  6.   <target    
  7.       android:name="v"    
  8.       android:animation="@anim/path_morph" />    
  9. </animated-vector>  </span>  

从上面代码我们可以看出配置了两个动画,一个是旋转动画一个是变化形状的动画。
旋转动画:

[html] view plain copy

 print?

  1. <objectAnimator    
  2.     xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:duration="6000"    
  4.     android:propertyName="rotation"    
  5.     android:valueFrom="0"    
  6.     android:valueTo="360"/>    

[html] view plain copy

 print?

  1. 那么在布局中怎么用呢。  

[html] view plain copy

 print?

  1. <LinearLayout    
  2.     xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     xmlns:tools="http://schemas.android.com/tools"    
  4.     android:id="@+id/container"    
  5.     android:layout_width="wrap_content"    
  6.     android:layout_height="wrap_content"    
  7.     android:layout_gravity="center"    
  8.     android:paddingBottom="@dimen/activity_vertical_margin"    
  9.     android:paddingLeft="@dimen/activity_horizontal_margin"    
  10.     android:paddingRight="@dimen/activity_horizontal_margin"    
  11.     android:paddingTop="@dimen/activity_vertical_margin"    
  12.     android:gravity="center_horizontal"    
  13.     android:orientation="vertical"    
  14.     tools:context=".ExampleActivity">    
  15.   <TextView    
  16.       android:layout_width="wrap_content"    
  17.       android:layout_height="wrap_content"    
  18.       android:layout_margin="@dimen/margin"    
  19.       android:text="@string/example_from_documentation"    
  20.       android:drawableBottom="@drawable/avd"/>    
  21.   <TextView    
  22.       android:layout_width="wrap_content"    
  23.       android:layout_height="wrap_content"    
  24.       android:layout_margin="@dimen/margin"    
  25.       android:text="@string/rotation_only"    
  26.       android:drawableBottom="@drawable/avd_rotation_only"/>    
  27.   <TextView    
  28.       android:layout_width="wrap_content"    
  29.       android:layout_height="wrap_content"    
  30.       android:layout_margin="@dimen/margin"    
  31.       android:text="@string/path_morph_only"    
  32.       android:drawableBottom="@drawable/avd_path_morph_only"/>    
  33. </LinearLayout>   

变化形状动画:

[html] view plain copy

 print?

  1. <span style="font-size:14px;"><objectAnimator    
  2.     xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:duration="3000"    
  4.     android:propertyName="pathData"    
  5.     android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"    
  6.     android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"    
  7.     android:valueType="pathType"/>  </span>  

3个TextView,我们只需要关注第一个TextView即可,因为其他都是一样的配置。
配置了一个avb也就是上面贴的animated-vector文件。

最后看一下Activity的启动动画代码:

[html] view plain copy

 print?

  1. TextView textView = (TextView) view;    
  2. for (final Drawable drawable : textView.getCompoundDrawables()) {    
  3.   if (drawable instanceof Animatable) {    
  4.     ((Animatable) drawable).start();    
  5.   }    
时间: 2024-11-02 05:08:30

Android VectorDrawable与AnimatedVectorDrawable的相关文章

svg矢量图绘制以及转换为Android可用的VectorDrawable资源

项目需要 要在快速设置面板里显示一个VoWiFi图标(为了能够区分出来图形,我把透明的背景填充为黑色了) 由于普通图片放大后容易失真,这里我们最好用矢量图(SVG(Scalable Vector Graphics))来做图标,而系统状态栏图标多是用vectorDrawable绘制,所以我们的最终目的就是绘制一个上图中样式的Android VectorDrawable xml图标.尤其是这种资源文件体积小放大又不失真,干嘛不用呢. VectorDrawable Android L开始提供了新的AP

Vectors For All (almost)

本文讲的是Vectors For All (almost), 经常阅读 Styling Android 的读者会知道我有多么喜欢用 VectorDrawable 和 AnimatedVectorDrawable .直到我在写这篇文章之前我还在等待 VectorDrawableCompat (译者注:之前大家以为官方会出兼容 Support ,后来官方使用了另外一种方案,详细内容可戳该链接),所以目前矢量图只能够在 API 21+ (Lollipop) 上面使用.然而,Android Studio

Vector For All (slight return)

本文讲的是Vector For All (slight return), 大多数 Styling Android 的读者都知道我特别喜欢 VectorDrawable 和 AnimatedVectorDrawable. 然而(在我写这篇文章时)我们仍然在期待 VectorDrawableCompat 发布,现在我们现在只能在 API 21 (Lollipop) 以及更高的版本上使用. 然而,Android Studio 添加了一些向后兼容的构建工具,这样我们就能在 Lolipop 之前的版本中使

awesome-android

awesome-android https://github.com/snowdream/awesome-android Introduction android libs from github System requirements Android Notice If the lib is no longer being maintained,please do not add it here. How To Contribute Step 1. Add a Item as follows:

Android矢量图之VectorDrawable类自由填充色彩_Android

2014年6月26日的I/O 2014开发者大会上谷歌正式推出了Android L,它带来了全新的设计语言Material Design,新的API也提供了这个类VectorDrawable .也就是android支持SVG类型的资源也就是矢量图.想到矢量图,自然就会想到位图,何为矢量图,何为位图?先来说说位图吧,我们经常用的png,jpg就是位图了,他是由一个单元一个单元的像素组成的.当小icon遇到大屏幕手机的时候,icon如果被撑开那就是马赛克一样啦.这可不是我们想要的.而矢量图正式和它相

如何玩转Android矢量图VectorDrawable

从5.0(API等级21)开始,android开始支持矢量图了.关于什么是矢量图以及矢量图有什么优缺点不在本文的涉及范围之内,具体可以参考矢量图百科.不过这里要提一下它的优点: 保存最少的信息,文件大小比位图要小,并且文件大小与物体的大小无关 任意放大矢量图形,不会丢失细节或影响清晰度,因为矢量图形是与分辨率无关的. 从以上两个优点来看,在项目中使用矢量图至少可以缩小我们apk包的尺寸,而且可以在屏幕适配时提供很大的方便,因为矢量图是分辨率无关的. 前面也说了,矢量图从21才开始支持.那么如果我

Android矢量图之VectorDrawable类自由填充色彩

2014年6月26日的I/O 2014开发者大会上谷歌正式推出了Android L,它带来了全新的设计语言Material Design,新的API也提供了这个类VectorDrawable .也就是android支持SVG类型的资源也就是矢量图.想到矢量图,自然就会想到位图,何为矢量图,何为位图?先来说说位图吧,我们经常用的png,jpg就是位图了,他是由一个单元一个单元的像素组成的.当小icon遇到大屏幕手机的时候,icon如果被撑开那就是马赛克一样啦.这可不是我们想要的.而矢量图正式和它相

如何玩转Android矢量图VectorDrawable_Android

从5.0(API等级21)开始,android开始支持矢量图了.关于什么是矢量图以及矢量图有什么优缺点不在本文的涉及范围之内,具体可以参考矢量图百科.不过这里要提一下它的优点: 保存最少的信息,文件大小比位图要小,并且文件大小与物体的大小无关任意放大矢量图形,不会丢失细节或影响清晰度,因为矢量图形是与分辨率无关的. 从以上两个优点来看,在项目中使用矢量图至少可以缩小我们apk包的尺寸,而且可以在屏幕适配时提供很大的方便,因为矢量图是分辨率无关的. 前面也说了,矢量图从21才开始支持.那么如果我想

Android群英传笔记——第七章:Android动画机制和使用技巧

Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中十分重要的一部分,从早期的Android版本中,由于动画机制和绘图机制的不健全,Android的人机交互备受诟病,Android从4.X开始,特别是5.X,动画越来越完善了,Google也开始重视这一方面了,我们本章学习的主要内容有 Android视图动画' Android属性动画 Android动