Android 5.X SVG矢量动画案例

来源:互联网 发布:mac 终端哪个好 编辑:程序博客网 时间:2024/06/06 02:24

案例展示


 

源码地址:
https://github.com/xiaoyinliuyun/SVGDemo
http://download.csdn.net/detail/xiaoyinliuyun/9882869

一.矢量动画的xml实现


矢量动画的组成

矢量动画展示到控件上需要三个文件:
1.<vector>:适量图形文件 位置:drawable文件夹 作用:图形原始形态
2.<objectAnimator>:属性动画文件 位置:animator文件夹 作用:动画展示方案
3.<animator-vector>:粘合剂文件 位置:drawable文件夹 作用:把2动画方案作用于1适量图形

五个xml案例展示图片:(详述其中三个)

案例一:摆锤


1.<vector>文件:t1_svg_demo.xml


<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="200dp"    android:height="200dp"    android:viewportHeight="200"    android:viewportWidth="200">    <group        android:name="line1"        android:pivotX="100"        android:pivotY="0"        android:rotation="0">        <path            android:pathData="M 100,0 L 100,100"            android:strokeColor="@color/colorPrimaryDark"            android:strokeWidth="20"            android:strokeLineCap="round"/>        <group            android:name="test1"            android:pivotX="100"            android:pivotY="100"            android:rotation="0">            <path                android:pathData="M 50,100                              A 50,50,0,1,1,150,100"                android:strokeColor="@color/colorAccent"                android:strokeWidth="20"                android:strokeLineCap="round"/>        </group>    </group></vector>

  • <vector>
width,height属性代表实际展示宽度,
viewportWidth,viewportHeight属性代表把宽高等比例分成多少份

  • <group>一个树形结构的图形组
内部包含<group>和<path>节点 
pivotX,pivotY代表<group>中心点(属性动画如果是rotation,这个中心点为旋转的中心点,内部的group跟随外部的group移动(基于指定中心点))
rotation代表图形组起始角度

  • <path>具体图形
strokeColor:空心图形
fillColor:实心图形
stokeLineCap:倒角
pathData:参数为具体绘图命令代码
  • pathData 
举例(android:pathData="M 50,100 A 50,50,0,1,1,150,100)

(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制
(A RX,RY,//半径
    XROTATION,//指椭圆的X轴于水平方向顺时针方向夹角)
    FLAG1,//1表示大弧度,0表示小弧度
    FLAG2,//1表示顺时针,0表示逆时针
    X,Y)://A大写时为绝对坐标,a小写时为相对坐标 画各种情况下的圆弧
(L X,Y):画直线到指定的坐标位置

2.<objectAnimator>属性动画文件:t1_anim_path.xml (作用于锤)


<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:propertyName="rotation"    android:valueFrom="100"    android:valueTo="260"    android:repeatMode="reverse"    android:repeatCount="60"    android:interpolator="@android:anim/accelerate_decelerate_interpolator"></objectAnimator>
t2_anim_path_line.xml(作用于杆)

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:propertyName="rotation"    android:valueFrom="-10"    android:valueTo="10"    android:repeatMode="reverse"    android:repeatCount="60"    android:interpolator="@android:anim/accelerate_decelerate_interpolator"></objectAnimator>

  • propertyName 
为rotation时,valueFrom和valueTo为起始角度,旋转的圆心为作用图形的<group>的中心点pivotX,pivotY。
  • interpolator
插值器,动画播放的状态

3.<animator_vector>粘合剂文件:t1_anim_svg_demo.xml (作为控件的资源文件)


<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/t1_svg_demo">    <target        android:animation="@animator/t1_anim_path"        android:name="test1" />    <target        android:animation="@animator/t1_anim_path_line"        android:name="line1" /></animated-vector>

  • <animated_vector>drawable属性指定对应的矢量图形
  • <target>把动画作用于指定名字的<group>或<path>

4.控件引用对应的粘合剂文件:


<ImageView   android:id="@+id/ivLoading"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:src="@drawable/t1_anim_svg_demo" />

5.播放动画,停止动画

ivPendulum1 = (ImageView) findViewById(R.id.ivPendulum1);restart(ivPendulum1.getDrawable());

private void restart(Drawable drawable) {        if (drawable instanceof Animatable) {            Animatable animatable = (Animatable) drawable;            if (animatable.isRunning()) animatable.stop();            animatable.start();        }}


案例二:返回按钮

1.<vector>文件:t4_svg_back.xml

<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="48dp"    android:height="48dp"    android:viewportHeight="100"    android:viewportWidth="100">    <group        android:name="back"        android:pivotX="50"        android:pivotY="50"        android:rotation="0">        <path            android:name="path1"            android:pathData="M 30,30 L 70,30"            android:strokeColor="@color/colorPrimaryDark"            android:strokeLineCap="round"            android:strokeWidth="5" />        <path            android:name="path2"            android:pathData="M 30,50 L 70,50"            android:strokeColor="@color/colorPrimaryDark"            android:strokeLineCap="round"            android:strokeWidth="5" />        <path            android:name="path3"            android:pathData="M 30,70 L 70,70"            android:strokeColor="@color/colorPrimaryDark"            android:strokeLineCap="round"            android:strokeWidth="5" />    </group></vector>

2.<objectAnimator>属性动画文件:t4_anim_path1.xml , t4_anim_path3.xml , t4_anim_back.xml

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="500"    android:propertyName="pathData"    android:valueFrom="M 30,30 L 70,30"    android:valueTo="M 50,30 L 70,50"    android:valueType="pathType"></objectAnimator>

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="500"    android:propertyName="pathData"    android:valueFrom="M 30,70 L 70,70"    android:valueTo="M 50,70 L 70,50"    android:valueType="pathType"></objectAnimator>

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="500"    android:interpolator="@android:anim/accelerate_decelerate_interpolator"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="180"></objectAnimator>

  • propertyName="pathData"

此时valueType要设置成pathType

valueFrom和valueTo参照<path>标签的命令

3.<animator_vector>粘合剂文件:t4_anim_svg_back.xml (作为控件的资源文件)

<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/t4_svg_back">    <target        android:animation="@animator/t4_anim_path1"        android:name="path1"/>    <target        android:animation="@animator/t4_anim_path3"        android:name="path3"/>    <target        android:animation="@animator/t4_anim_back"        android:name="back"/></animated-vector>


4.5.同案例一


案例三:太阳系

1.<vector>文件:t3_svg_target.xml

<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="400dp"    android:height="400dp"    android:viewportHeight="400"    android:viewportWidth="400">    <group>        <path android:fillColor="@color/sun"            android:pathData="M 190,200                              a 10,10,0,1,0,20,0                              a 10,10,0,1,0,-20,0" />        <group android:name="mercury"            android:pivotX="200"            android:pivotY="200"            android:rotation="0">            <path android:strokeColor="@color/path"                android:pathData="M 240,200                                  a 20,20,0,1,0,-80,0                                  a 20,20,0,1,0,80,0"/>            <path android:fillColor="@color/mercury"                android:pathData="M 236,200                                  a 4,4,0,1,0,8,0                                  a 4,4,0,1,0,-8,0"/>        </group>        <group android:name="venus"            android:pivotX="200"            android:pivotY="200"            android:rotation="0">            <path android:strokeColor="@color/path"                android:pathData="M 270,200                                  a 20,20,0,1,0,-140,0                                  a 20,20,0,1,0,140,0"/>            <path android:fillColor="@color/venus"                android:pathData="M 266,200                                  a 4,4,0,1,0,8,0                                  a 4,4,0,1,0,-8,0"/>        </group>        <group            android:name="earth"            android:pivotX="200"            android:pivotY="200"            android:rotation="0" >            <path android:strokeColor="@color/path"                android:pathData="M 300,200                                  a 20,20,0,1,0,-200,0                                  a 20,20,0,1,0,200,0"/>            <path android:fillColor="@color/earth"                android:pathData="M 295,200                                  a 5,5,0,1,0,10,0                                  a 5,5,0,1,0,-10,0"/>            <group android:name="moon"                android:pivotX="300"                android:pivotY="200"                android:rotation="0">                <path android:strokeColor="@color/path"                    android:pathData="M 320,200                                      a 2,2,0,1,0,-40,0                                      a 2,2,0,1,0,40,0"/>                <path android:fillColor="@color/moon"                    android:pathData="M 318,200                                      a 2,2,0,1,0,4,0                                      a 2,2,0,1,0,-4,0"/>            </group>        </group>        <group android:name="mars"            android:pivotX="200"            android:pivotY="200"            android:rotation="0">            <path android:strokeColor="@color/path"                android:pathData="M 360,200                                  a 20,20,0,1,0,-320,0                                  a 20,20,0,1,0,320,0"/>            <path android:fillColor="@color/mars"                android:pathData="M 356,200                                  a 4,4,0,1,0,8,0                                  a 4,4,0,1,0,-8,0"/>        </group>    </group></vector>

  • pathData用法扩展(画整圆)

举例:android:pathData="M 356,200
  a 4,4,0,1,0,8,0
  a 4,4,0,1,0,-8,0 "
a小写时为相对坐标
通过(8,0)到底第一点后,在基于第一点通过(-8,0)到底第二点(也就是起始点)从而画出整圆


2.<objectAnimator>属性动画文件:t3_anim_mercury.xml , t3_anim_venus.xml , t3_anim_earth.xml,t3_anim_moon.xml,t3_anim_mars.xml

duration设置的是按比例缩小的公转周期
插值器采用的是线性插值器

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="8770"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatMode="restart"    android:repeatCount="60"    android:interpolator="@android:anim/linear_interpolator"/>


<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="22470"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatMode="restart"    android:repeatCount="60"    android:interpolator="@android:anim/linear_interpolator"/>


<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="36900"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatMode="restart"    android:repeatCount="60"    android:interpolator="@android:anim/linear_interpolator"/>


<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="2732"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatMode="restart"    android:repeatCount="3650"    android:interpolator="@android:anim/linear_interpolator"/>

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="68700"    android:propertyName="rotation"    android:valueFrom="0"    android:valueTo="360"    android:repeatMode="restart"    android:repeatCount="60"    android:interpolator="@android:anim/linear_interpolator"/>


3.<animator_vector>粘合剂文件:t3_anim_svg_target.xml (作为控件的资源文件)

<?xml version="1.0" encoding="utf-8"?><animated-vector xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/t3_svg_target">    <target        android:animation="@animator/t3_anim_mercury"        android:name="mercury"/>    <target        android:animation="@animator/t3_anim_venus"        android:name="venus"/>    <target        android:animation="@animator/t3_anim_earth"        android:name="earth"/>    <target        android:animation="@animator/t3_anim_mars"        android:name="mars"/>    <target        android:animation="@animator/t3_anim_moon"        android:name="moon"/></animated-vector>


4.5.同案例一



二.矢量动画的Java实现


1.通过SVG在线编辑器 自动生成路径

http://editor.method.ac/

2.SVG在线编辑器使用方法:

(1)绘制基础图形



(2)Object->Convert to Path
(3)通过参数调整背景及图形

  

(4)View->Source 生成pathData字符串源码(选中的即为需要的路径数据)



3.svg for java 最简单实现步骤:

(1)SvgView控件实现
private void init() {        // 1.通过路径字符串生成路径Path        mPath = ExposedPathParser.createPathFromPathData(mPathData);        // 2.计算路径长度        PathMeasure pm = new PathMeasure(mPath, true);        mLength = pm.getLength();        // 3.设置开始时间        mStartTime = System.currentTimeMillis();        // 4.初始化Paint        mPaint = new Paint();        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setColor(Color.RED);        mPaint.setAntiAlias(true);        mPaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));}

@Overrideprotected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (mPath == null) return;        // 1.计算 绘制时间区间        long t = System.currentTimeMillis() - mStartTime;        // 2.根据 时间 计算当前相位        float phase = constrain(0, 1, t * 1f / mTraceTime);        // 3.根据 相位和总长 计算刷新的距离        float distance = INTERPOLATOR.getInterpolation(phase) * mLength;        // 4.设置 Paint 本次绘制效果        mPaint.setPathEffect(new DashPathEffect(new float[]{distance, mLength}, 0));        // 5.绘图        canvas.drawPath(mPath, mPaint);        // 6.判断是否完成,如果没有,继续刷新        if (t < mTraceTime)            ViewCompat.postInvalidateOnAnimation(this);}

(2)实用控件AnimatorSvgView请参照源码




源码地址:
https://github.com/xiaoyinliuyun/SVGDemo
http://download.csdn.net/detail/xiaoyinliuyun/9882869
原创粉丝点击