如何使用Android的VectorDrawable类如何绘制矢量图图

SVG学习--AnimatedVectorDrawable的使用 - 简书
SVG学习--AnimatedVectorDrawable的使用
之前我们演示的都是静态的SVG图片加载,其实这有点屈才了,其实通过属性动画的配合,svg还可以动起来
&vector&, &group&, &clip-path&, 和&path& 元素都有各自可以播放动画的属性,查阅你会找到每种元素到底有那些属性,以便针对这些属性播放特定的动画。我这边先列举一些
pathandroid:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径android:pathData 和 SVG 中 d 元素一样的路径信息。android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框android:strokeWidth 定义路径边框的粗细尺寸android:strokeAlpha 定义路径边框的透明度android:fillAlpha 定义填充路径颜色的透明度android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1android:trimPathOffset 设置路径截取的范围,取值范围从 0 到1android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.android:strokeMiterLimit 设置斜角的上限
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 值来指定的。
clip-path:定义当前绘制的剪切路径。注意,clip-path 只对当前的 group 和子 group 有效android:name 定义 clip path 的名字android:pathData 和 android:pathData 的取值一样。
vector:定义这个矢量图android:name 定义该drawable的名字android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dpandroid:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dpandroid:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_inandroid:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。android:alpha 该图片的透明度属性
下面我演示用的translateY/translateX在path是没有动画属性的,他是group属性上的,那么我们就将需要执行动画的部分都分别绑定到不同的group里面去
改造SVG文件
&vector xmlns:android="/apk/res/android"
android:width="96dp"
android:height="96dp"
android:viewportWidth="96.0"
android:viewportHeight="96.0"&
&group android:name="pathgroup"&
&group android:name="animgroup"&
android:fillColor="@color/colorPrimary"
android:pathData="M48,48 a16,24 0 1 1 6,8"/&
&group android:name="noanimgroup"&
android:fillColor="@android:color/holo_green_light"
android:pathData="M48,48 a16,24 0 0 1 6,8"/&
android:fillColor="@android:color/holo_purple"
android:pathData="M48,48 a16,24 0 1 0 6,8"/&
android:fillColor="@android:color/holo_orange_light"
android:pathData="M48,48 a16,24 0 0 0 6,8"/&
这里其实跟上篇文章的svg差别不大,我仅仅添加了group,让animgroup这个标签执行动画文件
既然是创建属性动画,那么我们在res下建立animator文件夹,创建一个文件为move.xml
&?xml version="1.0" encoding="utf-8"?&
&set xmlns:android="/apk/res/android"&
&objectAnimator
android:propertyName="translateY"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="-10"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:duration="500"&
&/objectAnimator&
关联动画文件与SVG图片
我们在drawable下建立一个主标签为animated-vector的文件animator_v
&?xml version="1.0" encoding="utf-8"?&
&animated-vector xmlns:android="/apk/res/android" android:drawable="@drawable/ic_a"&
android:animation="@animator/move"
android:name="animgroup"&
&/animated-vector&
主标签下的android:drawable是引用的SVG图片,然后我们在里面定义target,target的数量可以无限多个。android:animation就是我们的动画文件,同时android:name就是我们之前在group里面设置的name值
添加布局引用
&ImageView xmlns:app="/apk/res-auto"
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/animated_v"/&
注意这边一定要使用srcCompat,不然5.0以下兼容会出现问题
OK,到此为止,我们在xml中的配置就结束了,这时候你运行得到的依然是一张静态图片,如何动起来呢?我们需要在使用到这个imageview的地方去获取到这个drawable,然后start
ImageView imageview= (ImageView) findViewById(R.id.imageview);
((AnimatedVectorDrawableCompat) imageview.getDrawable()).start();
AnimatedVectorDrawableCompat
其他动画属性欣赏--pathData
android:propertyName="pathData",这个是加载在Path上动画,可以进行形状变化,有一点要注意,就是变化前的valueFrom必须跟结束的valueTo参数个数要相等,同时这些参数的类型要匹配。但是这玩意我只在android6.0上成功运行
来一个简单的正方形变成三角形的案例
首先画一个正方形
&vector xmlns:android="/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportWidth="100.0"
android:viewportHeight="100.0"&
android:name="square"
android:strokeColor="#FF000000"
android:strokeWidth="0.5"
android:pathData="M30,30 L90,30 L90,90 L30,90 z"/&
然后就是属性动画
&objectAnimator xmlns:android="/apk/res/android"
android:duration="1000"
android:repeatMode="reverse"
android:repeatCount="1"
android:propertyName="pathData"
android:valueType="pathType"
android:valueFrom="M30,30 L90,30 L90,90 L30,90 z"
android:valueTo="M60,30 L60,30 L90,90 L30,90 z" /&
再次强调参数的类型、数量是一致的
&animated-vector xmlns:android="/apk/res/android"
android:drawable="@drawable/ic_change_history_black_24dp"&
android:animation="@animator/translate"
android:name="square" /&
&/animated-vector&
其他动画属性欣赏--trimPathEnd/trimPathStart
这个一般用在渐进显示画笔路径,1的时候是当前状态,0的时候是对里面状态,所以我们一般从头画到结束,会选择的动画分别为
&objectAnimator
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:duration="5000"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear"&
&/objectAnimator&
&objectAnimator
android:propertyName="trimPathStart"
android:valueFrom="1"
android:valueTo="0"
android:duration="5000"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear"&
&/objectAnimator&
还是之前正方形的SVG图片,看看效果
SVG还有很多不兼容的地方,而且谷歌每次在更新的时候都有可能会改动之前的部分,所以这部分大家在使用过程中一定要多加留意,多多测试7288人阅读
android 开发(38)
安卓5.0Lollipop发布以来VectorDrawable作为安卓环境下的矢量化图形的方式一直由于兼容性问题而很少被用到,由于只能用于5.0以上系统,导致现在多少安卓机无法使用而一直被开发人员无限搁置。在官方给出兼容性的解决方案之前,开发者社区已经有几个解决方案了。比如:
但是就效果和易用性而言,我个人并不看好,其中MrVector已经停止维护,而vector-compat也已经很长时间没有更新过,而且经博主测试发现仅适用于Android gradle plugin 1.4以下的版本,1.5以后存在无法正确编译的问题。
官方也一直没有给出一个 VectorDrawableCompat 支持库来解决兼容性问题。
Android gradle plugin 1.5发布以后,加入了一个跟VectorDrawable有关的新功能。Android build tools 提供了另外一种解决兼容性的方案,如果编译的版本是5.0之前的版本,那么build tools 会把VectorDrawable生成对应的png图片,这样在5.0以下的版本则使用的是生成的png图,而在5.0以上的版本中则使用VectorDrawable
在build.gradle添加generatedDensities配置,可以配置生成的png图片的密度:
defaultConfig {
applicationId "com.liaoinstan.vectordrawablesupport"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
generatedDensities = ['hdpi', 'xhdpi']
不配置,默认全部生成。
那么,接下来测试一下:
创建一个支持5.0以下版本的工程,我这里最低支持到15,不配置generatedDensities 默认全部生成
defaultConfig {
applicationId "com.liaoinstan.vectordrawablesupport"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
在drawable下创建一个vector.xml配置一张矢量图:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500px"
android:height="500px"&
android:name="android"&
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298" /&
android:name="left_eye"
android:fillColor="#FFFFFF"
android:pathData="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438" /&
android:name="right_eye"
android:fillColor="#FFFFFF"
android:pathData="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438" /&
android:name="left_arm"
android:fillColor="#9FBF3B"
android:pathData="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z" /&
android:name="body"
android:fillColor="#9FBF3B"
android:pathData="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489H140.396z" /&
android:name="right_arm"
android:fillColor="#9FBF3B"
android:pathData="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z" /&
然后在布局中添加一个ImageView引用该矢量图:
android:id="@+id/imageView"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@drawable/vector" /&
效果如下:
然后打包编译,从工程目录下找到编译生成的apk文件,路径如下:
VectorDrawableSupport\app\build\outputs\apk
然后将apk使用解压软件解压,在res文件夹下可以找到生成的各个屏幕密度对应的资源文件:
里面分别为不同分辨率的屏幕生成了不同规格的png图片
这种方案缺失解决了目前存在的VectorDrawable 的向下兼容的问题,但是为VectorDrawable 提供了各种复杂动画效果的AnimatedVectorDrawable依然无法在5.0以下的机型使用。
目前也没有什么较好的解决方案,一般通过机型的适配来为不同安卓版本制作2种资源,一种是支持动画的给5.0以上机器使用,一种是不支持动画的给5.0以下的机型使用。在使用AnimatedVectorDrawable的时候,把 AnimatedVectorDrawable资源放到 drawable-v21 目录中,并且在 drawable 中提供一个和 AnimatedVectorDrawable 同名字的资源来在 5.0之前的版本使用,在这个 xml 文件中可以使用一个 selector 来替代这个动画。
注意有时候为了简洁可能会把VectorDrawable下的pathData放到string.xml中,然后在VectorDrawable下引用,如:
android:name="right_arm"
android:fillColor="#9FBF3B"
android:pathData="@string/mypath" /&
如果通过生成png来兼容5.0以下机型的话,会报pathData错误,编译器不会去读取string.xml,我也不知道为啥要这样限制,总之只能把pathData写到VectorDrawable下。
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="M 12, 4 L 10.59, 13 L 18.99, 13 L 12, 20z" /&
AnimatedVectorDrawable确实是一个非常实用的工具,能够通过配置来实现各种复杂的动画效果,让人眼前一亮,但是目前的兼容性问题却很让人头疼,改天再写写AnimatedVectorDrawable吧。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:306423次
积分:3624
积分:3624
排名:第8298名
原创:38篇
评论:179条
阅读:545783613人阅读
Android(21)
转载请注明出处:
项目需要 要在快速设置面板里显示一个VoWiFi图标(为了能够区分出来图形,我把透明的背景填充为黑色了)
由于普通图片放大后容易失真,这里我们最好用矢量图(SVG(Scalable Vector Graphics))来做图标,而系统状态栏图标多是用vectorDrawable绘制,所以我们的最终目的就是绘制一个上图中样式的Android
VectorDrawable xml图标。尤其是这种资源文件体积小放大又不失真,干嘛不用呢。
VectorDrawable
Android L开始提供了新的API&VectorDrawable&可以使用SVG类型的资源,也就是矢量图。在xml文件中的标签是&vector&
google官方API介绍:
This lets you create a drawable based on an XML vector graphic. It can be defined in an XML file with the&&vector&&element.
The vector drawable has the following elements:
具体属性和方法请参考官方说明
下面是一个官方例子:
&vector xmlns:android=&/apk/res/android&
android:height=&64dp&
android:width=&64dp&
android:viewportHeight=&600&
android:viewportWidth=&600& &
android:name=&rotationGroup&
android:pivotX=&300.0&
android:pivotY=&300.0&
android:rotation=&45.0& &
android:name=&v&
android:fillColor=&#000000&
android:pathData=&M300,70 l 0,-70 70,70 0,0 -70,70z& /&
&/group& &/vector&
显示效果(背景色应为透明)
如果想了解绘制原理,调至请调至文末点击W3C的连接。
接下来介绍一些常用的svg绘图工具
1.Inkscape
开源的多平台矢量图绘图工具,支持windows OS X Linux。支持导出为svg等格式图片,功能强大,与后面两个将要介绍的比较就是体积有点大,安装包就接近百兆了。
另外用这个生成的SVG文件,会带一些默认的属性,转化成VectorDrawable以后xml文件里也会有一些默认的属性,虽不影响显示效果,但会多出一些不必要的代码。
工作界面:
2.Boxy SVG
是一个Chrome应用(推荐)。支持导入,另存为,可以选中单个控件调整属性等。可能不好的地方就是你得安装Chrome浏览器吧,还有下载这个应用的时候得翻墙。
3.Janvas - The Online Vector Graphics Editor
也是Chrome应用,不过其实就是一个链接,打开后指向下面的地址
但是这个在线编辑器好像只能打开和保存文件到google driver,不推荐
这个东西没找到名字,点击下面的连接试用。添加到收藏夹,随时可用。便捷。
转换为VectorDrawable
找到两个在线转换的工具,都是Github上的开源项目。
1.Android SVG to VectorDrawable
Convert SVG to Android VectorDrawable XML resource
可能是这个工具开发比较早,有很多Star,基本的图形转换是可以的,但是,不支持文字!也就是说上面的图,如果我们转换的话,得到的结果只是一个椭圆,文字会丢失。
在线工具:
源码地址:
2.SvgToVectorDrawableConverter.Web
converter of SVG images to Android VectorDrawable XML resource files.
这个就比较好了,支持文本转换。
在线工具:
源码地址:
这里我把颜色改回了白色。使用的是Boxy SVG绘制,SvgToVectorDrawableConverter.Web转换。
Android Studio支持直接预览VectorDrawable矢量图,有了实时预览,也方便进行一些简单的修改。
这个图标最后应用到下拉的快速设置里面,在手机上的效果图就不上了。
展示一张稍复杂的图吧:
本文简单介绍了几款工具,目的能让新手快速的了解一下如何制作出自己需要的矢量图资源文件,在有需要做一张应用到Android应用/系统的矢量图时不至于措手不及。当然如过你牛逼到直接用记事本“绘图”的话,本文应该不适合你。
我发现我特别喜欢发掘一些能够提高生产力的小工具啊,哈哈哈。
知其然不知其所以然?想要了解的原理,跳转到W3C查看Scalable Vector Graphics (SVG) 1.1 (Second Edition)
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:111180次
积分:1666
积分:1666
排名:千里之外
原创:51篇
评论:49条
(2)(3)(1)(2)(2)(2)(1)(1)(1)(3)(3)(1)(2)(3)(4)(1)(1)(1)(1)(2)(5)(2)(15)VectorDrawable不同分辨率的drawable资源
VectorDrawable不同分辨率的drawable资源
编辑日期: 字体:
一、VectorDrawable
在android5.0(API Level 21)中,我们可以使用矢量图:vector drawable,vector drawable的特点是它不会因为图像的缩放而失真。在安卓开发中也就意味着你不需要为不同分辨率的设备定义不同大小的图片资源,只需一个vector drawable就够了。在安卓中与vector drawable资源对应的类是VectorDrawable。要创建一个vector drawable,你需要在xml的的元素下定义好vector drawable的形状数据。
下面的例子定义了一个心形的vector drawable:
&!-- res/drawable/heart.xml --&
&vector xmlns:android=&/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& /&
二、AnimatedVectorDrawable
AnimatedVectorDrawable可以让VectorDrawable动起来。
AnimatedVectorDrawable通过改变VectorDrawable的属性来让VectorDrawable呈现动画效果,其实现实际上是试用了属性动画。
通常定义一个AnimatedVectorDrawable需要以下三个xml文件:
1.vector drawable本身:res/drawable/中定义一个有元素的xml文件,参考上面对VectorDrawable的定义。
2.vector drawable的动画文件(Animated vector drawable):res/drawable/中定义一个有元素的xml文件。
3.一个或者多个属性动画文件:res/drawable/中定义一个有元素的xml文件。
Animated vector drawable可以让和元素的属性动态变化。定义一组path或者子group,而元素定义需要绘制的路径。当你想让VectorDrawable呈现动画效果,在定义VectorDrawable的时候需要为group和path的android:name属性设置一个唯一的名字,以便在Animated vector drawable中找到它们。比如
其中这里最让人不解的是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的图标是大有人在。
&!-- res/drawable/vectordrawable.xml --&
&vector xmlns:android=&/apk/res/android&
android:height=&64dp&
android:width=&64dp&
android:viewportHeight=&600&
android:viewportWidth=&600&&
android:name=&rotationGroup&
android:pivotX=&300.0&
android:pivotY=&300.0&
android:rotation=&45.0& &
android:name=&v&
android:fillColor=&#000000&
android:pathData=&M300,70 l 0,-70 70,70 0,0 -70,70z& /&
其中group的android:name为rotationGroup而path的android:name为v。
在Animated vector drawable中就分别通过rotationGroup和v找到vector drawable的group和path:
&!-- res/drawable/animvectordrawable.xml --&
&animated-vector xmlns:android=&/apk/res/android&
android:drawable=&@drawable/vectordrawable& &
android:name=&rotationGroup&
android:animation=&@anim/rotation& /&
android:name=&v&
android:animation=&@anim/path_morph& /&
&/animated-vector&
其中animation代表一个ObjectAnimator或者AnimatorSet ,在本例中,第一个animator将目标group旋转360度:
&!-- res/anim/rotation.xml --&
&objectAnimator
android:duration=&6000&
android:propertyName=&rotation&
android:valueFrom=&0&
android:valueTo=&360& /&
第二个animator是将vector drawable的path元素从一个形状转变到另一个形状。但是这两个形状必须满足一定的条件:必须要有一致的命令(command)个数(逗号分割开的为命令),并且每个命令的参数个数也必须一致。
&!-- res/anim/path_morph.xml --&
&set xmlns:android=&/apk/res/android&&
&objectAnimator
android:duration=&3000&
android:propertyName=&pathData&
android:valueFrom=&M300,70 l 0,-70 70,70 0,0
android:valueTo=&M300,70 l 0,-70 70,0
0,140 -70,0 z&
android:valueType=&pathType& /&
本文固定链接:
转载请注明:
作者:leehom
本博客主要是把自己的经验记录于此,方便自己以后查阅及其他遇到类似问题的朋友参考。如果你有觉得不错的文章,可以注册会员发布文章或者邮箱发给我文章地址,谢谢!
如果觉得文章还不错,请麻烦点下广告,算是赞助下本站服务器费用,谢谢!
您可能还会对这些文章感兴趣!

我要回帖

更多关于 矢量图绘制 的文章

 

随机推荐