VectorDrawable与AnimatedVectorDrawable

来源:互联网 发布:网络公关方案 编辑:程序博客网 时间:2024/06/05 04:50
public class

VectorDrawable                                    Added in API level 21

extends Drawable
java.lang.Object   ↳android.graphics.drawable.Drawable    ↳ android.graphics.drawable.VectorDrawable




简单了解SVG的一些命令

命令

名称

参数

M

moveto  移动到

(x y)+

Z

closepath  关闭路径

(none)

L

lineto  画线到

(x y)+

H

horizontal lineto  水平线到

x+

V

vertical lineto  垂直线到

y+

C

curveto  三次贝塞尔曲线到

(x1 y1 x2 y2 x y)+

S

smooth curveto  光滑三次贝塞尔曲线到

(x2 y2 x y)+

Q

quadratic Bézier curveto  二次贝塞尔曲线到

(x1 y1 x y)+

T

smooth quadratic Bézier curveto  光滑二次贝塞尔曲线到

(x y)+

A

elliptical arc  椭圆弧

(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+


注意:如果指令字母是大写的,例如M, 则表示坐标位置是绝对位置,参照全局坐标系;如果指令字母小写的,例如m, 参照父容器坐标系。



M、H、V、Z、L指令都很简单,我们看看其他指令


1.  C指令


<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="500" height="500" version="1.1" xmlns="http://www.w3.org/2000/svg">   <path style="fill:white;stroke:red;stroke-width:2"     d="M50,50 C100,100 400,100 450,50     M50,50 L100,100     M400,100 L450,50"   /></svg>



2.S指令




<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="500" height="500" version="1.1"xmlns="http://www.w3.org/2000/svg"><path style="fill:white;stroke:red;stroke-width:2"    d="M50,50 S250,250 450,50 </svg>



3.A指令(7个参数)


rx ry x-axis-rotation large-arc-flag sweep-flag x y

 

rx,ry指所在椭圆的半轴大小。


x-axis-rotation指椭圆的X轴与水平方向顺时针方向夹角,可以想像成一个水平的椭圆绕中心点顺时针旋转 x-axis-rotation的角度。

large-arc-flag只有两个值,1表示大角度弧线,0为小角度弧线。

sweep-flag只有两个值,确定从起点至终点的方向,1为顺时针,0为逆时针


x,y为终点坐标。







先定义一个200x200的画布,注意坐标系,原点是左上角的点。先移动点到(100,100),

再移动到(10,0),长短轴都是90,椭圆顺时针转0

度,由于没有图形与它相交,第二个参数0,无所谓。

第三个参数0表示逆时针画出。最后2个参数是终点坐标。






这个图与上面的图是一样的,但是指令的区别在于大小写,我们用小写的指令“a”,表示相对。

最后的180,0,与前面的a指令表示正向移动180距离,以前在(10,0)点,

x点坐标移动180就是190,。所以和上面的一样。











先看效果图






VectorDrawable



我们用svg画出一个心形

<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"    android:height="100dp"    android:width="100dp"    android:viewportWidth="32"    android:viewportHeight="32">    <path    android:fillColor="#ff5d15"    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>


height与width表示大小,与View的大小是一样的,viewportwidth与viewportheight表示一块画布,这样里面的path在绘制的时候,坐标空间的大小就是前面的viewportheight和viewportwidth,

上面的100dp与32有什么关系呢,32只是映射100dp。



AnimatedVectorDrawable


一些字符串资源

<span style="font-size:18px;"><string name="path_circle">    M 50,50    m -48,0    a 48,48 0 1,0 96,0    a 48,48 0 1,0,-96,0  </string>  <string name="path_face_left_eye">    M 35,40    m -7,0    a 7,7 0 1,0 14,0    a 7,7 0 1,0 -14,0  </string>  <string name="path_face_right_eye">    M 65,40    m -7,0    a 7,7 0 1,0 14,0    a 7,7 0 1,0 -14,0  </string>  <string name="path_face_mouth_sad">    M 30,75    Q 50,55 70,75  </string>  <string name="path_face_mouth_happy">    M 30,65    Q 50,85 70,65  </string>  <string name="heart">    M25.119,2.564c12.434,0.023,18.68,5.892,24.88,17.612  c6.2-11.721,12.446-17.589,24.877-17.612c13.81-0.025,25.035,10.575,25.061,23.66c0.033,23.708-24.952,47.46-49.938,71.212  C25.016,73.685,0.03,49.932,0.064,26.224C0.085,13.14,11.309,2.539,25.119,2.564z  </string>     <string name="cross">       M25,25L10,25 M25,25L40,25 M25,25L25,10 M25,25L25,40    </string>    <string name="rect">        M10,10L40,10 M40,10L40,40 M40,40L10,40 M10,40L10,10    </string></span>



让VectorDrawable动起来

<animated-vector    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/clock" >  <target      android:name="hours"      android:animation="@anim/hours_rotation" />  <target      android:name="minutes"      android:animation="@anim/minutes_rotation" /></animated-vector>

里面的drawable表示一个VectorDrawable资源
然后我们指定一个target,name就是VectorDrawable资源里节点的名字(path、group等),接着给该节点一个动画资源


res/drawable/clock.xml
<vector    xmlns:android="http://schemas.android.com/apk/res/android"    android:height="100dp"    android:width="100dp"    android:viewportHeight="100"    android:viewportWidth="100" >  <group      android:name="minutes"      android:pivotX="50"      android:pivotY="50"      android:rotation="0">    <path        android:strokeColor="@android:color/holo_green_dark"        android:strokeWidth="@integer/stroke_width"        android:strokeLineCap="round"        android:pathData="M 50,50 L 50,12"/>  </group>  <group      android:name="hours"      android:pivotX="50"      android:pivotY="50"      android:rotation="0">    <path        android:strokeColor="@android:color/holo_blue_dark"        android:strokeWidth="@integer/stroke_width"        android:strokeLineCap="round"        android:pathData="M 50,50 L 24,50"/>  </group>  <path      android:strokeColor="@android:color/holo_red_dark"      android:strokeWidth="@integer/stroke_width"      android:pathData="@string/path_circle"/></vector>

res/anim/hours_rotation
<objectAnimator    xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="8000"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="240"    android:interpolator="@android:anim/linear_interpolator"/>


res/anim/minutes_rotation
<objectAnimator    xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatCount="7"    android:interpolator="@android:anim/linear_interpolator"/>


最后我们必须手动启动动画
 private void animate(ImageView imageView) {        Drawable drawable = imageView.getDrawable();        if (drawable instanceof Animatable) {            ((Animatable) drawable).start();        }    }



看看笑脸的动画是怎么做到的
<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"                 android:drawable="@drawable/face" >  <target      android:name="mouth"      android:animation="@anim/smile" /></animated-vector>

res/drawable/face
<vector    xmlns:android="http://schemas.android.com/apk/res/android"    android:height="100dp"    android:width="100dp"    android:viewportHeight="100"    android:viewportWidth="100" >  <path      android:fillColor="@color/yellow"      android:pathData="@string/path_circle"/>  <path      android:fillColor="@android:color/black"      android:pathData="@string/path_face_left_eye"/>  <path      android:fillColor="@android:color/black"      android:pathData="@string/path_face_right_eye"/>  <path      android:name="mouth"      android:strokeColor="@android:color/black"      android:strokeWidth="@integer/stroke_width"      android:strokeLineCap="round"      android:pathData="@string/path_face_mouth_sad"/></vector>



res/anim/smile

<objectAnimator  xmlns:android="http://schemas.android.com/apk/res/android"  android:duration="3000"  android:propertyName="pathData"  android:valueFrom="@string/path_face_mouth_sad"  android:valueTo="@string/path_face_mouth_happy"  android:valueType="pathType"  android:interpolator="@android:anim/accelerate_interpolator"/>

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





最后我们看看心从小变大的效果,直接指定一个View的src是AnimatedVectorDrawable

<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/vector_double_heart">    <target        android:name="like"        android:animation="@anim/nulike_to_like"></target></animated-vector>


res/drawable/vector_double_heart

<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="100dp"    android:height="100dp"    android:viewportHeight="32"    android:viewportWidth="32">    <path        android:name="unlike"        android:fillColor="#666"        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" />    <group        android:name="like"        android:pivotX="16"        android:pivotY="16"        android:scaleX="0"        android:scaleY="0">        <path            android:fillColor="#ff5d15"            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" />    </group></vector>

定义了2个心。把最上面的缩放到0,这样你就可以看到最下面的心了。


res/anim/nulike_to_like

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:fillAfter="true"    android:repeatMode="reverse"    android:repeatCount="0"    android:duration="900"    android:shareInterpolator="true"    android:startOffset="0"    >    <objectAnimator        android:interpolator="@android:anim/accelerate_interpolator"        android:propertyName="scaleX"        android:valueFrom="0"        android:valueTo="1.0"></objectAnimator>    <objectAnimator        android:interpolator="@android:anim/accelerate_interpolator"        android:propertyName="scaleY"        android:valueFrom="0"        android:valueTo="1.0"></objectAnimator></set>




参考:http://www.w3school.com.cn/svg/index.asp

           http://www.zhangxinxu.com/wordpress/2014/06/deep-understand-svg-path-bezier-curves-command/

           http://mobile.51cto.com/news-478709.htm






0 0
原创粉丝点击