看完本文,每人送一台小黄车,掘金牌的~html
不得不说,矢量图在项目中用得少之又少,却很香!可缩放矢量图形(SVG)是一套语法规范,常在前端中使用,而VectorDrawable(Android中的矢量图)只实现了SVG的部分语法。使用VectorDrawable
代替位图能够减少 APK 的大小,由于能够针对不一样的屏幕密度调整同一文件的大小,而不会下降图片质量,同时能够实现一些复制的效果图。前端
能够从下面两个地方得到经常使用矢量图:android
Vector Asset Studio
工具
「Android版本兼容问题」web
因为兼容低版本问题,致使矢量图得不到推广吧?可是如今大多数手机系统都Android 5.0起步了吧。app
矢量图VectorDrawable
仅支持到Android 4.4,经过支持库可最低支持到Android 2.1。编辑器
矢量图动画AnimatedVectorDrawable
仅支持到Android 5.0,经过支持库最低支持到Android 3.0。 「Gralde配置」工具
android {
defaultConfig { vectorDrawables.useSupportLibrary = true } } dependencies { //须要 Android 支持库 23.2 或更高版本以及 Android Plugin for Gradle 2.0 或更高版本 implementation 'com.android.support:appcompat-v7:23.2.0' } 复制代码
「美图减压鉴赏:」 布局
经过Android Studio的Vector Asset Studio
工具来获取一张矢量图。post
根据我的喜爱配置Vector Assert。
会在drawable文件夹生成资源文件,例如这里生成
ic_menu.xml
文件:flex
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/> </vector> 复制代码
没了解过矢量图,相信是看不懂path
标签pathData
属性的内容。
在vector
标签设置矢量图大小,width
和height
属性分别为24dp
。viewportWidth
和viewportHeight
属性表示画布的大小,表示将矢量图等分的份数,这里划分为24*24。能够理解在一张24dp*24dp的图片上有24*24个小方格,经过这些小方格,能够绘制不一样图案。
path
能够理解为路径,图片绘制的内容。fillColor
属性表示填充颜色,pathData
属性表示在图片上做画内容。
pathData
属性的值是SVG的语法内容,经过下面的内容就能够了解pathData
属性值的含义了。
经常使用命令:
「M x,y」 移动到坐标(x,y)。M3,18表示将画笔移动到坐标(3,18)
「L x,y」从当前的位置画一条直线到指定的位置(x,y)。
「H x」 画水平线到x位置。
「V y」 画垂直线到y位置。
「Z」 闭合,链接终点和起点
「A rx,ry,xRotationAnagle,radianFlag,sweepFlag,x,y」 画弧线,理解为椭圆的一部分,rx
和ry
表示 x轴和y轴半径,即椭圆的长短轴问题;xRotationAnagle
表示x轴旋转角度(搞不明白用法);radianFlag
0表示取小弧度,1表示取大弧度;sweepFlag
0表示逆时针,表示1顺时针画弧线;x
和y
弧线的终点位置,起点位置为画笔所在的地方。
「C x1,y1,x2,y2,x3,y3」 三次贝赛曲线
「S x2,y2,x,y」 光滑三次贝塞尔曲线
「Q x1,y1,x2,y2」 二次贝赛曲线
「T x,y」 映射
ps:大写表示绝对坐标,小写表示相对坐标。
对pathData
标签内容进行解读:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M3,18 h18 v-2 L3,16 v2 z M3,13 h18 v-2 L3,11 v2 z M3,6 v2 h18 L21,6 L3,6 z"/> </vector> 复制代码
M3,18
将画笔移动到坐标(3,18)
;
h18
从坐标(3,18)
到坐标(21,18)
画一条水平直线;
v-2
从坐标(21,18)
到坐标(21,16)
画一条垂直直线;
L3,16
从坐标(21,18)
到坐标(3,16)
画一条直线;
v2
从坐标(3,16)
到坐标(3,18)
画一条垂直直线;
z
闭合起点和终点。
到这里,最底部的直线就会画出来了,其余两条线是相同原理。
「注意事项」:不要将pathData的值抽离出来放到string.xml
文件,否则在兼容5.0如下机型生成png图片,会报pathData错误。
那path
标签除了pathData
属性,还有哪些可用的属性呢?
path
标签path
标签可用属性:
name
:路径名称,可在其余地方引用,例如矢量图动画引用;
strokeWidth
:线条宽度,单位为
viewportHeight
或
viewportWidth
中的1等分;。
strokeColor
:线条颜色;
strokeAlpha
:线条透明度。
0f->1f
;
strokeLineJoin
:线条拐角的形状。圆角
round
、斜切尖角
miter
、斜角
bevel
,例如正方形的四个角;
strokeLineCap
:线条线帽形状。圆角
round
、正方形
square
、臂
butt
;
strokeMiterLimit
:斜线miter与strokeWidth的比例上限。若是比例值超过这个值,再也不显示尖角而是bevel斜角。当
strokeLineJoin
属性设置为
miter
才生效。
fillColor
:填充颜色;
fillType
:填充类型,取值
nonZero
、
evenOdd
;
fillAlpha
:填充透明度;
trimPathStart
:从路径开始位置剪掉比率的内容,留下剩下的,
0f->1f
;
trimPathEnd
:从路径开始位置截取比率的内容,留下截取的内容,
0f->1f
;
trimPathOffset
:
trimPathStart
或
trimPathEnd
的偏移量
0f->1f
;
例如:
XML布局以下:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="triangle" android:pathData="M3,18 h18 v-5 L3,13 v5 z " android:strokeWidth="1" android:strokeLineJoin="round" android:strokeAlpha="0.9" android:strokeColor="@color/white" android:trimPathStart="0.1" android:strokeLineCap="round" android:trimPathOffset="0.15" /> </vector> 复制代码
PreView效果以下:
group
标签group
标签主要是将多个path
标签组合起来,子标签也能够是group
标签,其属性做用于全部子标签,有如下属性:
name
: 定义
group
标签名称;
translateX
: x轴位移;
translateY
: y轴位移;
rotation
: 旋转;
scaleX
: x轴缩放;
scaleY
: y轴缩放;
pivotX
: 缩放与旋转参考点X;
pivotY
: 缩放与旋转参考点y; 栗子:
XML布局代码:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <group android:name="triangleGroup" android:rotation="10" android:translateX="1" android:translateY="1" android:scaleX="0.5f" android:scaleY="0.5f" android:pivotX="0.5" android:pivotY="0.5"> <path android:fillColor="@color/colorPrimary" android:pathData="M6,6 L9,12 H3 z" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineJoin="round" /> <path android:fillColor="@color/chart_color_1" android:pathData="M18,6 L21,12 H15 z" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineJoin="bevel" /> </group> </vector> 复制代码
效果图:
只要胆子大,没有实现不了的矢量图,加上点动画效果那就更炫酷吊了。属性动画了解多少呢?好文连接==>:Android属性动画,看完这篇够用了吧
「矢量图动画步骤」
轨迹动画主要利用属性动画设置矢量图的trimPathStart
或trimPahtEnd
属性。要正确实现轨迹动画的前提条件:矢量图是一笔画出的,不能存在屡次挪画笔的操做。
示例:
vector_text.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="240dp" android:height="240dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="pathText" android:pathData="M9,6 L12,12 L15,6.5 18,12 21,6" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> </vector> 复制代码
画了一个白色的W
:
2. 在
animator
文件夹下建立animator_text.xml
文件。定义一个属性动画,操做矢量图的trimPathEnd
属性。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="2000" android:propertyName="trimPathEnd" android:valueFrom="0" android:valueTo="1" android:repeatMode="reverse" android:repeatCount="infinite" android:valueType="floatType" /> //这里顺便操做矢量图的画笔颜色 <objectAnimator android:duration="2000" android:propertyName="strokeColor" android:valueFrom="@color/white" android:repeatMode="reverse" android:repeatCount="infinite" android:valueTo="@android:color/holo_blue_dark" android:valueType="colorType" /> </set> 复制代码
drawable
文件夹下建立
animator_vector_text.xml
文件,组合矢量图和属性动画,成为它两的粘合剂。因为兼容问题,须要在
drawable-v21
文件夹下建立。
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_text"> <target android:name="pathText" android:animation="@animator/animator_text" /> </animated-vector> 复制代码
animated-vector
标签的drawable
属性值是第一步定义的矢量图文件名。target
标签的name
属性是咱们在矢量图中定义的;而animation
属性则是第二部定义的属性动画文件名。
animator_vector_text
文件
<ImageView
android:id="@+id/iv" app:srcCompat="@drawable/vector_animator_text" android:layout_width="match_parent" android:layout_height="wrap_content" /> 复制代码
val animatable = iv.drawable as Animatable animatable.start() 复制代码
「效果图:」
路径动画是利用矢量图中相同的关键点进行变幻的过程。
Android 5.0前不支持路径动画。
示例:
vector_line.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="240dp" android:height="240dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="pathLine" android:pathData="M9,6 L12,6 L15,6 18,6 21,6" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> </vector> 复制代码
咱们定义了几个关键点,画了一条直线:
2. 在
animator
文件夹下建立animator_morphing.xml
文件。定义一个属性动画,操做矢量图的pathData
属性。valueFrom
是第一步建立直线矢量图的属性pathData
的值,valueTo
是W
矢量图的pathData
的值。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="2000" android:propertyName="pathData" android:valueFrom="M9,6 L12,6 L15,6 18,6 21,6" android:valueTo="M9,6 L12,12 L15,6.5 18,12 21,6" android:valueType="pathType" /> </set> 复制代码
drawable
文件夹下建立
animator_vector_line.xml
文件,组合矢量图和属性动画,成为它两的粘合剂。因为兼容问题,须要在
drawable-v21
文件夹下建立。
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_line"> <target android:name="pathLine" android:animation="@animator/animator_morphing" /> </animated-vector> 复制代码
animator_vector_text
文件
<ImageView
android:id="@+id/iv" app:srcCompat="@drawable/vector_animator_line" android:layout_width="match_parent" android:layout_height="wrap_content" /> 复制代码
val animatable = iv.drawable as Animatable animatable.start() 复制代码
「效果图」
到这里就结束了,下面是属于你们的小黄车~
实例demo演示,用了2小时给你们制做的小黄车,但愿不要嫌弃:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="300dp" android:height="300dp" android:viewportWidth="200" android:viewportHeight="200"> <!--左车轮--> <group android:name="leftWheel" android:pivotX="40" android:pivotY="70"> <path android:name="leftWheelAxle" android:pathData="M 40,70 L23,80M 40,70 L40,50 M 40,70 L57,80" android:strokeWidth="1" android:strokeColor="@color/white" /> <path android:pathData="M 60,70 A 20,20,0,1,1,60,69 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> <!--右车轮--> <group android:name="rightWheel" android:pivotX="130" android:pivotY="70"> <path android:name="rightWheelAxle" android:pathData="M 130,70 L113,80 M 130,70 L130,50 M 130,70 L147,80" android:strokeWidth="1" android:strokeColor="@color/white" /> <path android:pathData="M 150,70 A 20,20,0,1,1,150,69 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> <!--车链盒子--> <path android:name="chainBox" android:fillColor="@color/colorPrimary" android:pathData="M 35,62 h54 v12 H35 z" android:strokeWidth="1" android:strokeColor="@color/white" /> <!--车架--> <path android:pathData="M 50,69 L 65,40 L 80,69 M 86,65 L110,31 v 20 L130,70 " android:strokeWidth="2" android:strokeColor="@color/colorPrimary" android:strokeLineJoin="round" /> <!--前车轮挡板--> <path android:pathData="M105,73 A 20,20,0,1,1,125,85" android:strokeWidth="2" android:strokeColor="@color/colorPrimary" android:strokeLineJoin="round" android:trimPathEnd="0.4" /> <!--车把--> <path android:pathData="M 110,31 V20 l -10,-4 h -3 M110,21 l -4,-10 h-3" android:strokeWidth="2" android:strokeColor="@color/white" android:strokeLineCap="round" android:strokeLineJoin="round" /> <!--车篮--> <path android:fillColor="@color/white" android:pathData="M 111,41 h 21 v -12 H 111 z" android:strokeWidth="1" android:strokeColor="@color/white" android:strokeLineCap="square" android:strokeLineJoin="round" /> <!--掘金LOGO--> <path android:fillColor="@color/colorPrimary" android:pathData="M 121,30 L122,31 L121,32 L120,31 z" android:strokeWidth="0.5" android:strokeColor="@color/colorPrimary" android:strokeLineCap="square" android:strokeLineJoin="miter" /> <path android:pathData=" M119,33 L121,35,L123,33 M118,34 L121,37,L124,34" android:strokeWidth="0.5" android:strokeColor="@color/colorPrimary" android:strokeLineCap="square" android:strokeLineJoin="miter" /> <!--皮座--> <path android:fillColor="@color/white" android:pathData="M 55,40 h 20 v-4 H56 v-3h-2" android:strokeWidth="1" android:strokeColor="@color/white" android:strokeLineCap="square" android:strokeLineJoin="round" /> <!--脚踏板--> <group android:name="pedal" android:pivotX="82" android:pivotY="68"> <path android:pathData="M 82,68 L 98,80" android:strokeWidth="0.5" android:strokeColor="@color/white" android:strokeLineCap="round" /> <path android:fillColor="@color/white" android:pathData="M 96,80 A 2,2,0,1,1,96,81 z" android:strokeWidth="1" android:strokeColor="@color/white" /> </group> </vector> 复制代码
「预览图:」
2. 在
animator
文件夹下建立animator_wheel.xml
文件,实现车轮和脚踏旋转属性动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:interpolator="@android:interpolator/linear" android:propertyName="rotation" android:repeatCount="infinite" android:valueType="floatType" android:valueFrom="0f" android:valueTo="360f" android:repeatMode="restart" android:duration="2000"/> //能够再增长其余动画效果,例如颜色变化 </set> 复制代码
animator
文件夹下建立
animator_bicycle_left_to_right.xml
布局文件,实现单车从左到右移动属性动画:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX" android:valueFrom="-600f" android:valueTo="900f" android:valueType="floatType" android:repeatCount="infinite" android:repeatMode="restart" android:duration="9000" android:interpolator="@android:interpolator/linear" /> 复制代码
drawable
文件夹下建立
verctor_animator_bicycle.xml
文件,实现单车矢量图和属性动画的粘合剂,也就是最终的矢量图动画。因为兼容问题,须要在drawable-v21文件夹下建立。
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vertor_bicycle"> <target android:animation="@animator/animator_wheel" android:name="leftWheel"/> <target android:animation="@animator/animator_wheel" android:name="rightWheel"/> <target android:animation="@animator/animator_wheel" android:name="pedal"/> </animated-vector> 复制代码
verctor_animator_bicycle.xml
文件,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@color/black"> <ImageView android:id="@+id/iv" app:srcCompat="@drawable/verctor_animator_bicycle" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/btnStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="50dp" android:background="@color/white" android:padding="10dp" android:text="开始" android:textColor="@color/colorPrimary" android:textSize="16sp" /> </RelativeLayout> 复制代码
AppCompatActivity
中代码调用:
btnStart.setOnClickListener { val animatable = iv.drawable as Animatable animatable.start() } 复制代码
此时效果图: 7. 加上从左到右的属性动画:
btnStart.setOnClickListener { val animatable = iv.drawable as Animatable animatable.start() val animator = AnimatorInflater.loadAnimator(this, R.animator.animator_bicycle_left_to_right) animator.setTarget(iv) animator.start() } 复制代码
效果图:
好了哇,你们的小黄车已经造好,请给文章点个赞领取,若是不满意,能够自行定制小黄车哦~
「要啥自行车,想要个赞而已」
参考文章:
本文使用 mdnice 排版