Android 矢量动画的使用

阿里图标库

drawable->new->vector-Asset->loacl file->path 


 首先捋清关系~

我们拿到一个svg类型的图片 ,可以直接在ImageView 的 src 赋值 用.

如果我们想要控制 svg的 绘制,或者给他加一些动画效果


一:

这是一个svg,我们阿里图标库下载的

只有 一个path

需要给path  加一个name


二:

需要在Drawable 下创建animated-vector 

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/ic_zan"
    tools:targetApi="lollipop">

    <!--这里的name对应你在Path 里的name-->
    <!--animation 就是 这一段path 对应的 动画效果-->
    <target
        android:name="1"
        android:animation="@anim/rotate" />

    <!--<target-->
    <!--android:name="2"-->
    <!--android:animation="@anim/anim_cross_line" />-->

    <!--<target-->
    <!--android:name="3"-->
    <!--android:animation="@anim/anim_cross_line" />-->

</animated-vector>

三:

objectAnimator

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <!--sequentially 顺序执行    together 同时执行-->

    <!--【1】使用trimPathStart属性,valueFrom:0,valueTo:1-->

    <!--线条从起点缩短到终点,即初始截断部分是0%,从起点开始逐渐扩大到终点,达到100%。-->

    <!--【2】使用trimPathStart属性,valueFrom:1,valueTo:0-->

    <!--线条从终点增长到起点,即初始截断部分是100%,从终点开始逐渐缩小到起点,达到0%。-->

    <!--【3】使用trimPathEnd属性,valueFrom:0,valueTo:1-->

    <!--线条从起点增长到终点,即初始截断部分是100%,从起点开始逐渐缩小到终点,达到0%。-->

    <!--【4】使用trimPathEnd属性,valueFrom:1,valueTo:0-->

    <!--线条从终点缩短到起点,即初始截断部分是0%,从终点开始逐渐扩大到起点,达到100%。-->


    <objectAnimator
        android:duration="1600"
        android:propertyName="trimPathEnd"
        android:valueFrom="0"
        android:valueTo="1" />


</set>

四:

需要 srcCompat 引用

注意app 不是 Android


        <ImageView
            android:id="@+id/iv2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:srcCompat="@drawable/test"
            tools:ignore="VectorDrawableCompat" />

 MainAc

 Drawable drawable = iv2.getDrawable();
                if (drawable instanceof Animatable) {
                    ((Animatable) drawable).start();
                }

效果1



换一个动画

 <objectAnimator
        android:duration="1600"
        android:propertyName="trimPathEnd"
        android:valueFrom="0"
        android:valueTo="1" />

    <objectAnimator
        android:duration="1600"
        android:propertyName="trimPathStart"
        android:valueFrom="1"
        android:valueTo="0" />

 


然后是 图形变换

首先是来个svg

一个瓶子 一个赞 都是只有一个Path

现在想让 瓶子变成 赞

瓶子的svg 需要检查一下

 因为图形变化需要明确划分group

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">

    <group
        android:name="playgroup"
        android:pivotX="5"
        android:pivotY="5">

        <path
            android:name="play"
            android:fillColor="#1296db"
            android:pathData="M704,128a32,32 0,0 1,0 64h-21.33v160.79a10.67,10.67 0,0 0,1.09 4.69l180.87,369.6c28.48,58.22 4.38,128.49 -53.81,156.97A117.33,117.33 0,0 1,759.24 896L264.75,896c-64.8,0 -117.33,-52.53 -117.33,-117.33a117.33,117.33 0,0 1,11.95 -51.57l180.87,-369.62a10.67,10.67 0,0 0,1.09 -4.69L341.32,192h-21.33a32,32 0,0 1,-31.95 -30.12L288,160a32,32 0,0 1,32 -32zM755.97,650.67L268.01,650.67l-51.16,104.55A53.33,53.33 0,0 0,264.76 832L759.25,832a53.33,53.33 0,0 0,47.89 -76.78L755.98,650.67zM618.67,192L405.33,192v160.79a74.67,74.67 0,0 1,-7.59 32.82L299.33,586.67h425.32l-98.39,-201.07A74.67,74.67 0,0 1,618.67 352.8L618.67,192z" />

    </group>

</vector>

这里的playgroup  和 play 需要自己起上   也是一个 playgroup 代表在这个容器里 进行 变化 ,play 表示需要变化的 path

也就是 我们把 瓶子 的 Path  变换 成 赞 的path

突然转回来 发现 这些svg 需要特定的 转换才可以 

我找了 俩个 差不多的 svg图 总之他俩可以,然后开始转换


<ImageView
            android:id="@+id/iv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/xin_to_tuite"
            tools:ignore="VectorDrawableCompat" />

首先是R.drawable.xin_to_tuite

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/svg_xin"
    tools:ignore="NewApi">
    <!--默认图片-->

    <!-- 变化内容  默认->最终 -->
    <target
        android:name="play"
        android:animation="@anim/anim_xin_to_tuite" />

    <!-- 变化的动画 过程 旋转 -->
    <target
        android:name="playgroup"
        android:animation="@anim/anim_rotation" />

</animated-vector>

svg_xin

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="150dp"
    android:height="150dp"
    android:viewportWidth="24"
    android:viewportHeight="24">

    <group
        android:pivotX="12"
        android:pivotY="12"
        android:name="playgroup"
        >

        <path
            android:name="play"
            android:fillColor="#1296db"
            android:pathData="M 12.0,21.35 l -1.45,-1.32 C 5.4,15.36,2.0,12.28,2.0,8.5 C 2.0,5.42,4.42,3.0,7.5,3.0
                c 1.74,0.0,3.41,0.81,4.5,2.09 C 13.09,3.81,14.76,3.0,16.5,3.0 C 19.58,3.0,22.0,5.42,22.0,8.5
                c 0.0,3.78,-3.4,6.86,-8.55,11.54 L 12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 L 12.0,21.35" />

    </group>

</vector>

R.Anim_anim_xin_to_tuite

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <!--sequentially 顺序执行    together 同时执行-->

    <!--【1】使用trimPathStart属性,valueFrom:0,valueTo:1-->

    <!--线条从起点缩短到终点,即初始截断部分是0%,从起点开始逐渐扩大到终点,达到100%。-->

    <!--【2】使用trimPathStart属性,valueFrom:1,valueTo:0-->

    <!--线条从终点增长到起点,即初始截断部分是100%,从终点开始逐渐缩小到起点,达到0%。-->

    <!--【3】使用trimPathEnd属性,valueFrom:0,valueTo:1-->

    <!--线条从起点增长到终点,即初始截断部分是100%,从起点开始逐渐缩小到终点,达到0%。-->

    <!--【4】使用trimPathEnd属性,valueFrom:1,valueTo:0-->

    <!--线条从终点缩短到起点,即初始截断部分是0%,从终点开始逐渐扩大到起点,达到100%。-->


    <objectAnimator
        android:duration="500"
        android:propertyName="pathData"
        android:valueFrom="M 12.0,21.35 l -1.45,-1.32 C 5.4,15.36,2.0,12.28,2.0,8.5 C 2.0,5.42,4.42,3.0,7.5,3.0
                c 1.74,0.0,3.41,0.81,4.5,2.09 C 13.09,3.81,14.76,3.0,16.5,3.0 C 19.58,3.0,22.0,5.42,22.0,8.5
                c 0.0,3.78,-3.4,6.86,-8.55,11.54 L 12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35 C 12.0,21.35,12.0,21.35,12.0,21.35
                C 12.0,21.35,12.0,21.35,12.0,21.35 L 12.0,21.35"
        android:valueTo="M 22.46,6.0 l 0.0,0.0 C 21.69,6.35,20.86,6.58,20.0,6.69 C 20.88,6.16,21.56,5.32,21.88,4.31
                c 0.0,0.0,0.0,0.0,0.0,0.0 C 21.05,4.81,20.13,5.16,19.16,5.36 C 18.37,4.5,17.26,4.0,16.0,4.0
                c 0.0,0.0,0.0,0.0,0.0,0.0 L 16.0,4.0 C 13.65,4.0,11.73,5.92,11.73,8.29 C 11.73,8.63,11.77,8.96,11.84,9.27
                C 8.28,9.09,5.11,7.38,3.0,4.79 C 2.63,5.42,2.42,6.16,2.42,6.94 C 2.42,8.43,3.17,9.75,4.33,10.5
                C 3.62,10.5,2.96,10.3,2.38,10.0 C 2.38,10.0,2.38,10.0,2.38,10.03 C 2.38,12.11,3.86,13.85,5.82,14.24
                C 5.46,14.34,5.08,14.39,4.69,14.39 C 4.42,14.39,4.15,14.36,3.89,14.31 C 4.43,16.0,6.0,17.26,7.89,17.29
                C 6.43,18.45,4.58,19.13,2.56,19.13 C 2.22,19.13,1.88,19.11,1.54,19.07 C 3.44,20.29,5.7,21.0,8.12,21.0
                C 16.0,21.0,20.33,14.46,20.33,8.79 C 20.33,8.6,20.33,8.42,20.32,8.23 C 21.16,7.63,21.88,6.87,22.46,6.0 L 22.46,6.0"
        android:valueType="pathType" />

    <!--valueFrom 放瓶子 的path-->
    <!--valueTo 放 赞 的path-->


</set>

R.anim_anim_rotation

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <!--sequentially 顺序执行    together 同时执行-->

    <!--【1】使用trimPathStart属性,valueFrom:0,valueTo:1-->

    <!--线条从起点缩短到终点,即初始截断部分是0%,从起点开始逐渐扩大到终点,达到100%。-->

    <!--【2】使用trimPathStart属性,valueFrom:1,valueTo:0-->

    <!--线条从终点增长到起点,即初始截断部分是100%,从终点开始逐渐缩小到起点,达到0%。-->

    <!--【3】使用trimPathEnd属性,valueFrom:0,valueTo:1-->

    <!--线条从起点增长到终点,即初始截断部分是100%,从起点开始逐渐缩小到终点,达到0%。-->

    <!--【4】使用trimPathEnd属性,valueFrom:1,valueTo:0-->

    <!--线条从终点缩短到起点,即初始截断部分是0%,从终点开始逐渐扩大到起点,达到100%。-->


    <objectAnimator
        android:duration="1600"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="360" />


</set>

运行


现在让他可以控制状态

<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:ignore="NewApi">

    <item android:id="@+id/state_on"
        android:drawable="@drawable/svg_tuite"
        android:state_checked="true"/>

    <item android:id="@+id/state_off"
        android:drawable="@drawable/svg_xin" />

    <transition
        android:fromId="@id/state_off"
        android:toId="@id/state_on"
        android:drawable="@drawable/xin_to_tuite" />

    <transition
        android:fromId="@id/state_on"
        android:toId="@id/state_off"
        android:drawable="@drawable/tuite_to_xin" />

</animated-selector>
final ImageView iv2 = findViewById(R.id.iv2);

        iv2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                isTwitterChecked = !isTwitterChecked;
                final int[] stateSet = {android.R.attr.state_checked * (isTwitterChecked ? 1 : -1)};
                iv2.setImageState(stateSet, true);

            }
        });

就是把上面的反过来.


现在感觉还可以 ,研究一下为啥会报错  Can't morph from

这个

于是乎找到了 别人的记录

https://github.com/bonnyfone/vectalign

https://www.jianshu.com/u/4d3da5286550

然后顺着填进去

<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:ignore="NewApi">

    <item android:id="@+id/state_on"
        android:drawable="@drawable/vectalign_vector_drawable_end"
        android:state_checked="true"/>

    <item android:id="@+id/state_off"
        android:drawable="@drawable/vectalign_vector_drawable_start" />


    <transition
        android:fromId="@id/state_on"
        android:toId="@id/state_off"
        android:drawable="@drawable/vectalign_animated_vector_drawable_end_to_start" />

    <transition
        android:fromId="@id/state_off"
        android:toId="@id/state_on"
        android:drawable="@drawable/vectalign_animated_vector_drawable_start_to_end" />

</animated-selector>

感觉有点大

 

动画不好?

原来这里没有动画

那手动加上去

分别对他们进行修改添加

vectalign_animated_vector_drawable_end_to_start.xml

 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:drawable="@drawable/vectalign_vector_drawable_end"
     tools:ignore="NewApi">
     <target
         android:name="v"
         android:animation="@anim/vectalign_morph_animator_end_to_start" />

     <!-- 变化的动画 过程 旋转 -->
     <!-- 变化的动画 过程 旋转 -->
     <target
         android:name="playgroup"
         android:animation="@anim/anim_rotation_dao" />


 </animated-vector>

vectalign_animated_vector_drawable_start_to_end.xml

 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:drawable="@drawable/vectalign_vector_drawable_start"
     tools:ignore="NewApi">
     <target
         android:name="v"
         android:animation="@anim/vectalign_morph_animator_start_to_end" />

     <!-- 变化的动画 过程 旋转 -->
     <target
         android:name="playgroup"
         android:animation="@anim/anim_rotation" />

 </animated-vector>

vectalign_vector_drawable_end.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="100dp"
     android:width="100dp"
     android:viewportHeight="1154"
     android:viewportWidth="1154" >

    <group
        android:pivotX="577"
        android:pivotY="577"
        android:name="playgroup"
        >
     <path
         android:name="v"
         android:strokeColor="#000000"
         android:strokeWidth="2"
         android:fillColor="#0099CC"
         android:pathData="M 64.67,512.0 h 0.0 c 2.03,-148.27,27.78,-271.04,103.07,-344.26 v 0.0 C 240.96,92.45,363.73,66.7,512.0,64.67 c 148.27,2.03,271.04,27.78,344.26,103.07 h 0.0 C 931.55,240.96,957.3,363.73,959.33,512.0 c -2.03,148.27,-27.78,271.04,-103.07,344.26 v 0.0 C 783.04,931.55,660.27,957.3,512.0,959.33 c -148.27,-2.03,-271.04,-27.78,-344.26,-103.07 C 92.45,783.04,66.7,660.27,64.67,512.0 L 64.67,512.0 M 493.37,338.05 H 493.37 l 147.6,147.6 l -321.56,0.01 c -14.56,0.0,-26.36,11.8,-26.36,26.36 v 0.0 c 0.0,14.56,11.79,26.36,26.36,26.36 h 0.0 l 321.56,-0.01 l -147.61,147.59 c -10.29,10.29,-10.29,26.98,0.0,37.28 v 0.0 c 10.29,10.29,26.98,10.29,37.28,0.0 L 530.64,723.24 m 0.0,0.0 h 0.0 l 192.6,-192.6 c 1.22,-1.22,2.32,-2.58,3.28,-4.02 v 0.0 c 0.43,-0.65,0.73,-1.35,1.1,-2.03 h 0.0 c 0.46,-0.83,0.96,-1.63,1.32,-2.51 V 522.07996 c 0.37,-0.88,0.58,-1.81,0.84,-2.72 c 0.21,-0.73,0.5,-1.44,0.65,-2.19 c 0.68,-3.41,0.68,-6.93,0.0,-10.34 c -0.14,-0.71,-0.41,-1.37,-0.61,-2.07 c -0.27,-0.95,-0.5,-1.92,-0.88,-2.85 c -0.35,-0.85,-0.84,-1.61,-1.27,-2.41 c -0.38,-0.71,-0.7,-1.44,-1.15,-2.12 c -0.97,-1.44,-2.06,-2.79,-3.28,-4.02 l -192.6,-192.59 c -10.29,-10.29,-26.98,-10.29,-37.28,0.0 c -10.29,10.29,-10.29,26.98,0.01,37.28 L 493.37,338.05 " />
    </group>
</vector>

vectalign_vector_drawable_start.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="100dp"
     android:width="100dp"
     android:viewportHeight="1154"
     android:viewportWidth="1154" >

    <!--1154/2-->
    <group
        android:pivotX="577"
        android:pivotY="577"
        android:name="playgroup"
        >
     <path
         android:name="v"
         android:strokeColor="#000000"
         android:strokeWidth="2"
         android:fillColor="#0099CC"
         android:pathData="M 905.2,144.9 h -785.0 c -31.3,0.0,-56.7,25.6,-56.7,57.3 v 7.7 C 63.50001,209.9,63.50001,209.9,63.50001,209.9 c 0.0,31.6,25.4,36.4,56.7,36.4 h 785.0 C 905.2,246.29999,905.2,246.29999,905.2,246.29999 c 31.3,0.0,56.7,-4.7,56.7,-36.4 v -7.7 C 961.9,202.2,961.9,202.2,961.9,202.2 c 0.0,-31.7,-25.4,-57.3,-56.7,-57.3 C 905.2,144.9,905.2,144.9,905.2,144.9 L 905.2,144.9 M 800.7,459.8 H 120.2 l 0.0,0.0 l 0.0,0.0 c -31.3,0.0,-56.7,25.6,-56.7,57.3 v -13.2 c 0.0,31.6,25.4,57.3,56.7,57.3 h 680.5 l 0.0,0.0 l 0.0,0.0 c 31.3,0.0,56.7,-25.6,56.7,-57.3 v 13.2 c 0.0,-31.6,-25.4,-57.3,-56.7,-57.3 L 800.7,459.8 m -104.4,315.0 h -576.0 l 0.0,0.0 c -31.3,0.0,-56.7,25.6,-56.7,57.3 v 7.7 c 0.0,31.6,25.4,36.4,56.7,36.4 h 576.0 c 31.3,0.0,56.7,-4.7,56.7,-36.4 V 832.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 l 0.0,0.0 c 0.0,0.0,0.0,0.0,0.0,0.0 c 0.0,-31.6,-25.4,-57.2,-56.7,-57.2 L 696.3,774.8 " />
    </group>
</vector>

pivot 代表动画的中心  这里viewportHeight/2  就可以了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值