android中利用矢量图VectorDrawable打造酷炫动画
来源:互联网 发布:滨州行知中学暴力事件 编辑:程序博客网 时间:2024/05/18 12:38
1. 初识矢量图SVG与VectorDrawable
位图:有一个一个像素点组成的,放大会失真
矢量图:实际是一条path路径,每一个像素点是根据GPU实时计算出来,放大缩小不会失真
SVG和Vector的区别:
SVG,即Scalable Vector Graphics 矢量图,这种图像格式在前端中已经使用的非常广泛了,详见WIKI:https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
Vector,在Android中指的是Vector Drawable,也就是Android中的矢量图,详见:https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html
SVG:通常在前端中使用,是一套语法规范,GPU根据该规范绘制图片。SVG中会有很多标签用于绘制图片,如:rest、circle、polyline、line、path等。
Vector:通常在Android中使用,只实现了SVG语法中的path标签,可以视为简单化的矢量图。
SVG在加载过程中,效率比较低,而android的Vector只采用了SVG的path标签,如此设计就是为了提高SVG加载的效率
首先我们看一下位图、SVG图和Vector图片之间的一个大小关系
同样一张图片,PNG格式的5.6K,而SVG的2.6K,经过压缩后的Vector格式的图片只有1.5K,这是实用Vector图片的第二个好处,除了支持随意放大缩小之外,还极大减小占用体积。
Vector常用语法了解:
Vector中利用不同字母来代表不同含义,实现图片的绘制,下面我们简单看一下这三个指令:
- 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():关闭路径
上面的指令看着都很好理解,了解了上面的指令用法,基本就可以绘制常见的SVG图片了。。。
下面看一个简单的例子
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth=“500.0" android:viewportHeight=“500.0"> <path android:fillColor="#FF000000" android:pathData=“M100,100 L400,100 L100,400 Z"/></vector>
Vector中,android:width和android:height就是图片在手机上显示的大小,android:viewportWidth和android:viewportHeight可以理解为,我门把图片分成了500*500的小等分,我们在绘制时,以500为基线坐标,在这些坐标上绘制图片,显示图片时,不管图片多大,基线坐标是不变的,这是SVG格式图片不失真的主要原因;android:fillColor自然是绘制图片的颜色,最重要的就是android:pathData了,Vector就是根据pathData来绘制路径的。
有些人会觉得,简单图形手写pathData还行,可是比较复杂的图形怎么办呢,当然有绘制工具了,这里介绍一个SVG Editor:http://editor.method.ac/,我们可以在这行面绘制复杂的数量图形,然后导出SVG格式的图像,而android中无法直接使用SVG格式的图,所以我们可以通过http://inloop.github.io/svg2android/来进行SVG到Vector的转化,是不是很方便呢。。
2. VectorDrawable兼容性问题
VectorDrawable是在android L中提出来的,也就是说VectorDrawable只兼容minSDK>=21的版本,这个限制是非常大的,我们知道,目前市面上的Android版本比较混乱,各种版本的android手机都存在,这就导致VectorDrawable系统兼容性非常差。
VectorDrawable可以为我们的应用带来很多好处,Google也非常重视VectorDrawable的发展,后来在Gradle Plugin1.5中,Google为VectorDrawable做了兼容,主要实现是这样的:
当手机设备系统版本>=21 —> 实用Vector
当手机设备系统版本<21 —->将Vector转化为PNG格式显示,而这一步转化是在编译时自动完成的
我们可以看出来,这种兼容实际上并不好,既增加了兼容的成本,效果上也做了很多限制,Vector图片可以做很多动画(后面会讲),这些效果在21版本以下就没法使用。
而VectorDrawable真正的春天要等到AppCompat23.2的到来,Google在AppCompat23.2中增加了VectorDrawable全版本兼容,它使得静态的VectorDrawable可以支持到android2.1+,而动态的VectorDrawable可以支持到android3.0+的设备,这两个版本几乎已经包含了市面上90%+的android手机设备。
3. Android studio中如何使用VectorDrawable
Android studio中提供了一个Vector Asset工具,可以很方便的使用矢量图,通过File->New->Vector Asset打开,打开界面如图:
我们可以选择Material Icon来看studio为我们提供的大量Vector的Icon供我们去实用,当然也可以通过Local File来导入我们自定义的SVG Icon。当我们选择好Icon后,点击next->finish,studio会在drawable下为我们创建相应的Vector文件。
那么自定义的Icon是怎么来的呢,我们一般的开发者是无法熟练的制作SVG的图片,一般这些Icon是由设计师给我们制作好的,可是对于个人开发者而言,没有这种条件,那我我们可以通过http://iconfont.cn/来下载我们所需要的SVG的Icon,这是阿里巴巴为我们提供的图标库,里面的Icon还是比较丰富的。
3.1 静态的VectorDrawable
在studio使用Vector之前,我们首先需要设置gradle的配置,使得我们的项目支持VectorDrawable,我们打开项目的build.gradle文件,在android标签的defaultConfig标签中增加一行vectorDrawables.useSupportLibrary = true的配置,这样我们的项目就可以使用VectorDrawable了,前面也提到了VectorDrawable的兼容性问题,我们需要在dependencies标签中引用AppCompat23.2+的版本来使得Vector支持多版本,通常我们创建项目时,studio会自动为我们引入最新的AppCompat版本,这点我们可以不用自己去配置。
android { defaultConfig { vectorDrawables.useSupportLibrary = true }}dependencies { compile 'com.android.support:appcompat-v7:25.3.1’}
在控件中使用VectorDrawable其实很简单,我们可以把VectorDrawable当作一个普通的PNG图像来使用。
在ImageView/ImageButton中,我们只需要将android:src改变为app:srcCompat=“@drawable/vector_image”即可。
例如我们有一个名字为ic_face_black_24dp.xml的VectorDrawable图像,要把他使用在ImageView中来,我们引入代码如下:
<ImageView android:layout_width="100dp" android:layout_height="100dp" app:srcCompat="@drawable/ic_face_black_24dp”/>
这样,我们就可以在ImageView中显示一个静态的VectorDrawable,ImageView的宽高指定任意值,Vector图片都不会失真。这里有个地方需要注意,我们的Activity需要继承AppCompatActivity才可以正常显示VectorDrawable。
在Button中,我们通过app:srcCompat设置Vector图片作为背景时,会发现不起作用,Google的解释是像Button这样带有状态的控件,我们不可以直接使用app:srcCompat来设置背景图片,但是,可以通过selector来设置不同点击态的背景
如我们创建了一个bt_bg_vector.xml的selector:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_face_black_24dp" android:state_pressed="true"/> <item android:drawable="@drawable/ic_assignment_ind_black_24dp"/></selector>此时,我们在Button中引用bt_bg_vector.xml作为点击态的背景,代码如下:
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bt_bg_vector" />
如此,我们就可以方便的在ImageView、ImageButton、Button中设置静态的VectorDrawable,是不是跟png图片使用差别不大。
3.2 动态的VectorDrawable
前面我们看到了VectorDrawable的一些优势,比如:体积小、支持任意放大缩小等,但这并不足以让开发者放弃位图而转向VectorDrawable,下面我们来看一下VectorDrawable又一个惊天大优势,可以方便的使用动画。
在VectorDrawable中要使用属性动画,我们需要使用animated-vector,animated-vector其实也是一个XML文件,我们可以理解为配置动画的粘合剂,animated-vector将我们的目标VectorDrawable图像和所需要的属性动画animator进行了连接。
animated-vector代码如下所示:
<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_thumbs_up_down_black_24dp"> <target android:name="arrow_left" android:animation="@animator/anim_left" /> <target android:name="arrow_right" android:animation="@animator/anim_right" /> </animated-vector>
其中android:drawable是VectorDrawable图片名称,android:name是对应VectorDrawable中group的name(group后面再介绍),android:animation是要移动的属性动画,animated-vector标签在现在的Android Studio中实际上是会报错的,但这个并不影响编译和运行,属于Android Studio的Bug。
ic_thumbs_up_down_black_24dp代码如下:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0"> <group android:name="arrow_left"> <path android:fillColor="#FF559955" android:pathData="M12,6c0,-0.55 -0.45,-1 -1,-1L5.82,5l0.66,-3.18 0.02,-0.23c0,-0.31 -0.13,-0.59 -0.33,-0.8L5.38,0 0.44,4.94C0.17,5.21 0,5.59 0,6v6.5c0,0.83 0.67,1.5 1.5,1.5h6.75c0.62,0 1.15,-0.38 1.38,-0.91l2.26,-5.29c0.07,-0.17 0.11,-0.36 0.11,-0.55L12,6z" /> </group> <group android:name="arrow_right"> <path android:fillColor="#FFaa3333" android:pathData="M22.5,10h-6.75c-0.62,0 -1.15,0.38 -1.38,0.91l-2.26,5.29c-0.07,0.17 -0.11,0.36 -0.11,0.55L12,18c0,0.55 0.45,1 1,1h5.18l-0.66,3.18 -0.02,0.24c0,0.31 0.13,0.59 0.33,0.8l0.79,0.78 4.94,-4.94c0.27,-0.27 0.44,-0.65 0.44,-1.06v-6.5c0,-0.83 -0.67,-1.5 -1.5,-1.5z" /> </group></vector>
因为属性动画要改变绘制的图片属性来实现动画,可是path标签中并没有这种属性,因此,VectorDrawable要想使用属性动画,就需要用group标签来封装path标签,将属性动画作用在group标签中,这里使用group标签将vector图片分成了两组,如果图片比较复杂,会将其分成多组。
上面准备工作做好后,就可以在我们代码中直接使用了,使用也和普通Vector图片一样,如下:
<ImageView android:id="@+id/arrow" android:layout_width="100dp" android:layout_height="100dp" app:srcCompat="@drawable/arrow_anim" />这样,我们在Activity中直接调用改属性动画,使它运行就OK了。
arrow = (ImageView) findViewById(R.id.arrow);Drawable drawable = arrow.getDrawable();if(drawable instanceof Animatable){ ((Animatable)drawable).start();}这只是一个简单的属性动画例子,我们可以类似的实现更多复杂的动画效果。。。
3.3 VectorDrawable打造路径动画
这个搜索框的动画我们在很多地方都见过,如果使用普通的绘制动画去实现,还是有一定难度的,可是利用VectorDrawable来实现这种动画效果将非常容易只需要几行代码就可以搞定。
下面是一个searchbar的VectorDrawable,xml如下:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="150dp" android:height="24dp" android:viewportHeight="24" android:viewportWidth="150"> <path android:name="search" android:pathData="M141,17 A9,9 0 1,1 142,16 L149,23" android:strokeAlpha="0.8" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeWidth="2"/> <path android:name="bar" android:pathData="M0,23 L149,23" android:strokeAlpha="0.8" android:strokeColor="#000000" android:strokeLineCap="square" android:strokeWidth="2"/></vector>
这其实就是我们android应用中常见的搜索框,我们将这个Vector分为两个path,一个path就是一个放大镜的图标,另外一个就是一条直线,那么我们现在需要给这个searchbar一个动画效果,但我们并不需要对图片进行平移、缩放或变色这种基本的动画,我们需要改变这个图片的路径,VectorDrawable给我们提供了这种比较绚丽的动画效果,那就是trimPathStart属性。trimPathStart属性可以模拟Vector图片的路径生成,就像人拿了一个画笔,一点一点绘制出我们这个图片一样。trimPathStart的使用和属性动画其它属性的使用相同,属性动画文件如下anim_bar.xml:
<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:androd="http://schemas.android.com/apk/res/android" androd:duration="1500" androd:propertyName="trimPathStart" androd:repeatCount="infinite" androd:repeatMode="reverse" androd:valueFrom="0" androd:valueTo="1" androd:valueType="floatType"></objectAnimator>
trimPathStart代表绘制路径,valueFrom=“0" valueTo="1"代表线条bar从无到有开始绘制。跟anim_bar.xml相似,我们只给线条设置了动画,还需要给search图标设置动画,设置方式和anim_bar.xml几乎相同,命名为anim_search.xml。
我们设置好这个属性动画后,就可以animated-vector中直接使用这个属性动画,将该动画和我们的searchbar图片结合,animated-vector的xml文件如下searchbar_anim.xml:
<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/searchbar"> <target android:animation="@animator/anim_search" android:name="search"/> <target android:animation="@animator/anim_bar" android:name="bar"/></animated-vector>这样,我们就可以在Image中直接使用searchbar_anim,来实现我们的搜索动画了。
<ImageView android:id="@+id/search_bar" android:layout_width="200dp" android:layout_height="50dp" app:srcCompat="@drawable/searchbar_anim" />在activity中使用如下代码开始动画:
if(searchBar.getDrawable() instanceof Animatable){ ((Animatable)searchBar.getDrawable()).start();}
学好VectorDrawable,我们可以很方便的实现许多较复杂的动画效果,今天就先介绍这么多了。。。。
项目gitHub地址:https://github.com/gjnm/AndroidDraw
阅读全文
0 0
- android中利用矢量图VectorDrawable打造酷炫动画
- Android矢量图VectorDrawable及动画
- Android 矢量图(VectorDrawable)及动画(AnimatedVectorDrawable)
- Android 矢量图(VectorDrawable)及动画(AnimatedVectorDrawable)
- Android使用SVG矢量图打造酷炫动画效果
- Android利用vectordrawable实现轨迹动画
- VectorDrawable(矢量图)
- 矢量图VectorDrawable
- VectorDrawable矢量图
- Android VectorDrawable与SVG 实现炫酷动画
- Android VectorDrawable SVG矢量图 xml格式
- android 矢量图的打造
- 矢量图VectorDrawable轻松实现箭头左右移动动画
- Android svg VectorDrawable 动画效果
- Android中使用SVG矢量图打造多边形图形框架
- android开发游记:VectorDrawable矢量图兼容性问题的解决方案
- android矢量图之VectorDrawable ,自由又方便的填充色彩
- 如何使用Android的VectorDrawable类绘制矢量图
- linux下用rpm 安装jdk
- rabbitMQ安装详细的步骤以及案例演示、集群方法
- 《魂斗罗归来》之代理模式VS装饰模式
- 计算并输出一个三位数的各位、十位和百位数字之和。
- Oracle expdp定时备份脚本
- android中利用矢量图VectorDrawable打造酷炫动画
- css3的媒体查询
- MT6737 Android N 平台 Audio系统学习----ALSA Driver
- Jenkins + maven + git 实现持续集成
- Hadoop与Spark算法分析(四)——PageRank算法
- Shiro AuthenticationException 身份认证异常
- 高并发生成唯一订单号
- Thinkpad E470重装WIN7系统后,重启进入boot menu的问题
- c#索引器