VectorDrawable:适应不同分辨率的drawable资源

这是VectorDrawable的系列翻译文章,看到大牛的成果转载来分享!

来自泡在网上的日子.


这篇文章是对VectorDrawable的简单介绍,主要参考了android官方文档。更详细的讲解请参考stylingandroid网站的3篇文章https://blog.stylingandroid.com/vectordrawables-part-1/ ,或者关注本站将发表的翻译版本。

一、VectorDrawable

在android5.0(API Level 21)中,我们可以使用矢量图:vector drawable,vector drawable的特点是它不会因为图像的缩放而失真。在安卓开发中也就意味着你不需要为不同分辨率的设备定义不同大小的图片资源,只需一个vector drawable就够了。在安卓中与vector drawable资源对应的类是VectorDrawable。要创建一个vector drawable,你需要在xml的<vector>的元素下定义好vector drawable的形状数据。

下面的例子定义了一个心形的vector drawable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- res/drawable/heart.xml -->
<vector xmlns:android= "http://schemas.android.com/apk/res/android"
     <!-- intrinsic size of the drawable -->
     android:height= "256dp"
     android:width= "256dp"
     <!-- size of the virtual canvas -->
     android:viewportWidth= "32"
     android:viewportHeight= "32" >
 
   <!-- draw a path -->
   <path android:fillColor= "#8fff"
       android:pathData= "M20.5,9.5
                         c-1.955,0,-3.83,1.268,-4.5,3
                         c-0.67,-1.732,-2.547,-3,-4.5,-3
                         C8.957,9.5,7,11.432,7,14
                         c0,3.53,3.793,6.257,9,11.5
                         c5.207,-5.242,9,-7.97,9,-11.5
                         C25,11.432,23.043,9.5,20.5,9.5z"  />
</vector>

其中这里最让人不解的是pathData里面的那些数字,正是这些数字让这个drawable呈现出心形。pathData指的是绘制一个图形所需要的路径信息,那么问题来了,我怎么知道该如何绘制呢?

w3c的文档中详细讲解了绘制的规则:http://www.w3.org/TR/SVG11/paths.html#PathData 。其实在svg格式的图像中也是使用这种规则,而且在安卓中android.graphics.Path api对路径的定义也差不多是这种规则。

虽然有对path 规则的绘制教程,但是要创造出现有安卓中各种图标的效果是很难的,要让VectorDrawable有实际价值,肯定不能让开发者去想办法实现这些图形的绘制,而是原本就有很多现成的图像可用,8000个已分类好的扁平化图标(PNG/SVG/WEBFONT)  从网上的搜索结果来看svg的图标是大有人在。

 

二、AnimatedVectorDrawable

AnimatedVectorDrawable可以让VectorDrawable动起来。

AnimatedVectorDrawable通过改变VectorDrawable的属性来让VectorDrawable呈现动画效果,其实现实际上是试用了属性动画。

通常定义一个AnimatedVectorDrawable需要以下三个xml文件:

1.vector drawable本身:res/drawable/中定义一个有<vector>元素的xml文件,参考上面对VectorDrawable的定义。

2.vector drawable的动画文件(Animated vector drawable):res/drawable/中定义一个有<animated-vector>元素的xml文件。

3.一个或者多个属性动画文件:res/drawable/中定义一个有<objectAnimator>元素的xml文件。

Animated vector drawable可以让<group>和<path>元素的属性动态变化。<group>定义一组path或者子group,而<path>元素定义需要绘制的路径。当你想让VectorDrawable呈现动画效果,在定义VectorDrawable的时候需要为group和path的android:name属性设置一个唯一的名字,以便在Animated vector drawable中找到它们。比如

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


其中group的android:name为rotationGroup而path的android:name为v。

在Animated vector drawable中就分别通过rotationGroup和v找到vector drawable的group和path:

1
2
3
4
5
6
7
8
9
10
<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android= "http://schemas.android.com/apk/res/android"
   android:drawable= "@drawable/vectordrawable"  >
     <target
         android:name= "rotationGroup"
         android:animation= "@anim/rotation"  />
     <target
         android:name= "v"
         android:animation= "@anim/path_morph"  />
</animated-vector>

其中animation代表一个ObjectAnimator或者AnimatorSet ,在本例中,第一个animator将目标group旋转360度:

1
2
3
4
5
6
<!-- res/anim/rotation.xml -->
<objectAnimator
     android:duration= "6000"
     android:propertyName= "rotation"
     android:valueFrom= "0"
     android:valueTo= "360"  />


第二个animator是将vector drawable的path元素从一个形状转变到另一个形状。但是这两个形状必须满足一定的条件:必须要有一致的命令(command)个数(逗号分割开的为命令),并且每个命令的参数个数也必须一致。

1
2
3
4
5
6
7
8
9
<!-- res/anim/path_morph.xml -->
     <objectAnimator
         android:duration= "3000"
         android:propertyName= "pathData"
         android:valueFrom= "M300,70 l 0,-70 70,70 0,0   -70,70z"
         android:valueTo= "M300,70 l 0,-70 70,0  0,140 -70,0 z"
         android:valueType= "pathType"  />
</set>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值