当Android遇到SVG

  • 内容
  • 评论
  • 相关

矢量图SVG

从Android 5.0开始,Android允许开发者使用SVG图片作为图片资源,有关SVG的更多信息可以查看w3school上面的相关介绍。

矢量图有什么优点呢?首先,矢量图不会失真,不管放大多少倍,矢量图都是无损的,其次,矢量图的大小往往是jpg图片的十几分之一,很适合作为程序中使用,而且结合Android退出的矢量图动画,更能做出一些很炫酷的动效,下面我就来介绍下,如何在Android中使用矢量图。

获取一张矢量图并导入

首先想要获取矢量图资源,强烈推荐阿里巴巴图标库,其次,Android Studio也自带了全套的Material Design图标,很是nice。导入方式也很简单,首先在res文件夹上面右键,如下图所示就可以导入SVG图片了,可以选择Material Design中的矢量图或者导入我们自己下载的矢量图。

导入以后的矢量图在drawable文件夹下面,具体是如下形式,显示出来是一个向左的箭头,关键的是(整个文件只有352B不到1KB!!!!)

vector标签介绍

其中android:width以及android:height不用多说,说的是图片的大小,重点是android:viewportWidth以及android:viewportHeight,这两个属性代表的含义是将前面定义的宽高等分为多少份,上面的例子中就是将24dp分成24份,这样就有了一个24x24的坐标系,然后path代表的是线,android:pathData就是这条线中一些点的坐标,具体可以查看SVG语法。

通过上面的分析,我们可以知道,其实vector类似于描述了一个坐标系,然后通过path等设置一系列的点、线在坐标系中绘制图形,这也是为什么SVG图片不失真的原因。至于上面定义的 android:width="24dp"与android:height="24dp",我们在使用的时候,可以设置控件的宽高,让其被拉伸,毕竟不会失真。

SVG图片的兼容之路

最前面也说了,SVG图像是Android 5.0以后引入的,在5.0之前使用矢量图会怎么样呢?经过我的实验是,啥事都木有,正常显示,先放下手里的板砖听我解释,其实看看下面这张图就知道了。可以看到,在drawable-anydpi-v21文件夹里面的是矢量图,其他几个png图片是Android Studio自动帮我们生成的,当设备版本大于5.0的时候,使用矢量图,5.0以下的时候,会使用png图片。

不过上面也提到了,我们使用矢量图的一个重大原因是矢量图比较小巧,别看上图中显示的是1.99kb,那是被自动对齐以后的,如果编译器帮我们生成了png,那不是与我们的初衷相悖么。

关于这一点,可以参看官方文档如果只想使用SVG图片,那么需要修改 build.gradle 文件以及使用com.android.support:appcompat-v7:23.2.0 +

如果使用Gradle版本较低

在布局文件中使用

可以看到,我这里使用的是app:srcCompat,并且使用此View的Activity必须继承AppCompatActivity,如果不使用app:srcCompat会直接崩溃,如果不继承AppCompatActivity,那么图片就没了,程序运行时改变可以直接调用mSvgImg.setImageResource方法。可参见官方文档

其他控件

对于Button来说,使用 app:srcCompat 没有啥效果,不过我们可以取巧,为Button设置一个android:background为selector,然后在selector中使用SVG图像即可,不过,会崩溃!!!

解决方法,在Activity中加入如下代码

不过设置的selector无效,只能显示selector中默认的那个SVG图片。参考链接:http://www.jianshu.com/p/e3614e7abc03

SVG图片动画

终于到了激动人心的动画时刻了,其实对于Android目前来说,一般使用SVG图片用来进行一些nice的动画效果,如下图。使用传统动画都无法实现这种效果。

首先要使用SVG图片动画,其实与我们上面使用SVG图片类似,首先需要一个SVG图片,上图中的图片为。

上面name为search的代表那个搜索图标,下面name为bar的代表下划线,之所以这里添加了name属性,是为了让我们在进行动画的时候,能控制指定部分的图像。

有了SVG图片,那么我们还需要使用animated-vector标签来将动画与SVG图像联系在一起。如下

可以看到animated-vector中的android:drawable="@drawable/searchbar"代表需要执行动画的SVG图片,里面的target标签一看就懂,name就是我们在上面指定的name,android:animation就是代表在指定的name上面需要进行的动画。

好了,接下来我们指定动画就可以了,可是我们使用什么区指定动画呢?答案就是属性动画。因为SVG标签path、grou、vector、clip-path都有自己的属性,所以我们可以使用属性动画动态设置其属性,这样就完成动画了。下面贴出其有效属性。

标签 属性名 含义 取值范围 类型
<vector> alpha 透明度 0-1 floatType
<group> rotation 旋转角度 0-360 floatType
pivotX 旋转中心X floatType
pivotY 旋转中心Y ? floatType
scaleX X轴缩放 floatType
scaleY Y轴缩放 floatType
translateX X轴平移 floatType
translateY Y轴平移 floatType
<path> pathData ? ? ?
fillColor 填充色 ? colorType
strokeColor 描边色 ? colorType
strokeWidth 描边宽 ? ?
strokeAlpha 描边透明度 ? ?
fillAlpha 填充透明度 0-1 floatType
trimPathStart 路径开始到结束 0-1 floatType
trimPathOffset ? ? ?
<clip-path> pathData ? ? ?

?号表示不确定或者未实验,官方文档:https://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html?hl=zh-cn

下面贴出anim_searchbar_out.xml,其他的可查看文末源码地址。

可以看到,设置trimPathStart从1-0,表示先从全部显示慢慢"缩到"没有,然后无限循环,不停倒放,个人实验发现android:valueType不是必须写明的。

然后通过app:srcCompat将animated-vector设置给ImageView即可。

最后启动动画代码

至此,我们已经能够在Android 2.1以上版本上面使用SVG图片了,并且也能使用SVG动画了。

源码地址:https://github.com/CB2Git/BlogDemoRepository/tree/master/VectorDemo

评论

0条评论

发表评论

邮箱地址不会被公开。