动画矢量图(简单几步就能动起来)
VonLander
9年前
<p style="text-align:center"><img src="https://simg.open-open.com/show/55f8c66b7176fbed5940185f5ba6304c.gif"></p> <p>尽管 AnimatedVectorDrawableCompat (自从2016年二月份–Support Library 23.2.0)已经出来有一段时间了,Google官方却一直没有提供一份使用教程。你很难搜到相关可靠的文章,也没有什么能把这个东西完完整整的呈现出来。</p> <p>所以接下来我尝试将所有必要知识精简成你所能理解的东西。</p> <h2><strong>你需要做的事:</strong></h2> <h3><strong>1.在你的build.gradle文件中添加AppCompat依赖</strong></h3> <pre> <code class="language-java">compile 'com.android.support:appcompat-v7:25.0.0' </code></pre> <ul> <li>我使用了(此时)最新版本 25.0.0 ,但是只要从 23.2.0 开始任何版本可以正常工作</li> </ul> <h3><strong>2.创建vector drawable(矢量图)文件</strong></h3> <ul> <li>它能被赋予动画效果</li> <li>vector drawable文件必须被放在你项目的res/drawable文件夹</li> <li>更多的相关内容点 这里 (译注:官方文档需KX上网) <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24"> <group android:name="menu" android:pivotX="12" android:pivotY="12"> <group android:name="bottom_container" android:pivotX="20" android:pivotY="17"> <path android:name="bottom" android:pathData="M4,17,L20,17" android:strokeColor="#000" android:strokeLineCap="square" android:strokeLineJoin="miter" android:strokeMiterLimit="10" android:strokeWidth="2"/> </group> <group android:name="stem_container" android:pivotX="12" android:pivotY="12"> <path android:name="stem" android:pathData="M4,12,L20,12" android:strokeColor="#000" android:strokeLineCap="square" android:strokeLineJoin="miter" android:strokeMiterLimit="10" android:strokeWidth="2"/> </group> <group android:name="top_container" android:pivotX="20" android:pivotY="7"> <path android:name="top" android:pathData="M4,7,L20,7" android:strokeColor="#000" android:strokeLineCap="square" android:strokeLineJoin="miter" android:strokeMiterLimit="10" android:strokeWidth="2"/> </group> </group> </vector> </code></pre> </li> </ul> <p>上面的代码描绘的是一个基础的黑色菜单(汉堡包)图标:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/206155e288513d054bbcaece3f83aa64.png"></p> <h3><strong>3.创建动画文件</strong></h3> <ul> <li>它们指定了 vector 的动画部分</li> <li>可以将多个动画分别指定给一个 vector drawable的不同的部分</li> <li>vector 不同的部分用 name 标签指定(例如 menu , bottom_container , bottom , stem_container , stem , top_container , top )</li> <li>动画文件根元素既可以是 set 也可以是 objectAnimator</li> <li>这些文件需要放在res/anim目录下</li> </ul> <p>接下来的代码展现了 top_container 动画,它定义了四个属性, translateX , translateY , scaleX 以及 rotation :</p> <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:name="top_container" android:duration="700" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="translateX" android:startOffset="500" android:valueFrom="0" android:valueTo="-1.41421356" android:valueType="floatType"/> <objectAnimator android:name="top_container" android:duration="700" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="translateY" android:startOffset="500" android:valueFrom="0" android:valueTo="5" android:valueType="floatType"/> <objectAnimator android:name="top_container" android:duration="700" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="scaleX" android:startOffset="500" android:valueFrom="1" android:valueTo="0.5" android:valueType="floatType"/> <objectAnimator android:name="top_container" android:duration="700" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:propertyName="rotation" android:startOffset="500" android:valueFrom="0" android:valueTo="45" android:valueType="floatType"/> </set> </code></pre> <p style="text-align:center"><img src="https://simg.open-open.com/show/55daab662e9b672cd87dd9b0915c4aca.gif"></p> <h3><strong>4.创建animate-vector drawable文件</strong></h3> <ul> <li>animated-vector 将所有的内容都联系在一起( vector drawable文件和所有的 animation 文件)</li> <li>需要将它放在你项目的res/anim目录下</li> </ul> <pre> <code class="language-java"><?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/vector_menu_back" tools:ignore="NewApi"> <target android:name="top_container" android:animation="@anim/anim_top_container"/> <target android:name="stem_container" android:animation="@anim/anim_stem_container"/> <target android:name="bottom_container" android:animation="@anim/anim_bottom_container"/> <target android:name="menu" android:animation="@anim/anim_menu"/> </animated-vector> </code></pre> <p>需要注意的是:</p> <p>如果你的 minSdkVersion 小于21(如果大于的话,那我真的不知道你为什么会考虑用 AnimatedVectorDrawableCompat …正常用 AnimatedVectorDrawable 就行了),Android Studio可能会在你的 animated-vector 文件中弹出一个静态检查警告:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/00741937341ba6f06350a649fef9ae9d.png"></p> <p>不要担心这个警告!如果你的代码没有错误,你的 AnimatedVectorDrawableCompat 会忽略掉它并且能够正常工作。当然如果你不想再看到警告,可以添加 tools:ignore="NewApi" :</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/7e59a7ade1d279f10ef1120c21e960d4.png"></p> <h3><strong>5.编辑你的build.gradle文件</strong></h3> <ul> <li>在你的 build.gradle 文件中,将 vectorDrawables.useSupportLibrary = true 添加进 android 部分的 defaultConfig 内</li> <li>你需要这行代码,这样你的 animated-vector 才能兼容API小于 Lollipop版本的系统</li> </ul> <pre> <code class="language-java">android { compileSdkVersion 24 buildToolsVersion "24.0.3" defaultConfig { applicationId "com.junyuan.wukongnew" minSdkVersion 21 targetSdkVersion 24 versionCode 1 versionName "1.0" vectorDrawables.useSupportLibrary = true } ... } </code></pre> <h3><strong>6.将你的AnimatedVectorDrawableCompat设置到ImageView或者ImageButton</strong></h3> <ul> <li>你可以用 app:srcCompat 把它添加进xml文件</li> </ul> <pre> <code class="language-java"><ImageView android:id="@+id/iv_animated" android:layout_width="48dp" android:layout_height="48dp" app:srcCompat="@drawable/animated_vector_menu_back"/> </code></pre> <ul> <li>或者通过java代码:</li> </ul> <pre> <code class="language-java">final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(this, R.drawable.animated_vector_menu_back); animatedIv.setImageDrawable(avd); </code></pre> <h3><strong>7.在你需要的时候开启动画</strong></h3> <ul> <li>获得 AnimatedVectorDrawableCompat 的引用(或者是它的一个实现类– Animatable ),如果你的 AnimatedVectorDrawableCompat 是通过java代码添加的,可以直接使用这个对象的引用(你可以跳过这步):</li> </ul> <pre> <code class="language-java">final Animatable animatable = (Animatable) animatedIv.getDrawable(); </code></pre> <ul> <li>开启动画</li> </ul> <pre> <code class="language-java">animatable.start() </code></pre> <p style="text-align:center"><img src="https://simg.open-open.com/show/d42d50dddcc0dcfdc218387abfd9df65.gif"></p> <h2><strong>好消息和坏消息</strong></h2> <p>让我们先来听听好消息:</p> <p>你可以很轻松通过 Roman Nurik 的AndroidIconAnimator这个工具(尽管当前它是预览版,但是也足够有用了)实现步骤1-3。它可以将svg文件和你所指定的动画元素转换成 animated-vector drawable文件</p> <p>有一件很有意思的事情是导出来的来的 animated-vector 文件使用了 aapt 工具的一些非常厉害的功能,导出来的drawable文件包含了全部动画所需的代码(包括 vector drawable和 animation 文件)。就是将步骤1-3的所有文件都包含在一个文件里。</p> <p>坏消息来了:</p> <p>AnimatedVectorDrawableCompat 在API小于21时有一些限制:</p> <p>Chris Banes 的 文章 中指出:</p> <p>animate vectors 在API小于21的平台上工作时同样有一些限制,当前在这些平台上有一下这几点限制:</p> <p>路径绘制(PathType evaluator),这被用来从一个路径绘制到另一个路径</p> <p>路径插值器,这被用来定义一个灵活的插值器(展现成一个路径)以代替系统自动生成的,比如说线性插值器(LinearInterpolator)</p> <p>按路径移动,这很少能用到,几何图形能在限制路径上来回运动</p> <p>大致意思就是你可以忘了 pathData 元素的动画 pathData ,我们只能期望谷歌的天才们能研究一个方法将这个功能兼容到低版本的系统上去。</p> <p> </p> <p>来自:https://besttao.github.io/2016/11/30/[译]动画矢量图(简单几步就能动起来)/</p> <p> </p>