[译]动画矢量图(简单几步就能动起来)

   2016-12-01 0
核心提示:尽管 AnimatedVectorDrawableCompat (自从2016年二月份–Support Library 23.2.0)已经出来有一段时间了,Google官方却一直没有提供一份使用教程。你很难搜到相关可靠的文章,也没有什么能把这个东西完完整整的呈现出来。 所以接下来我尝试将所有必要知识精

尽管 AnimatedVectorDrawableCompat (自从2016年二月份–Support Library 23.2.0)已经出来有一段时间了,Google官方却一直没有提供一份使用教程。你很难搜到相关可靠的文章,也没有什么能把这个东西完完整整的呈现出来。

所以接下来我尝试将所有必要知识精简成你所能理解的东西。

你需要做的事:

1.在你的build.gradle文件中添加AppCompat依赖

compile 'com.android.support:appcompat-v7:25.0.0'
  • 我使用了(此时)最新版本 25.0.0 ,但是只要从 23.2.0 开始任何版本可以正常工作

2.创建vector drawable(矢量图)文件

  • 它能被赋予动画效果
  • vector drawable文件必须被放在你项目的res/drawable文件夹
  • 更多的相关内容点 这里 (译注:官方文档需科学上网)
    <?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>
    

上面的代码描绘的是一个基础的黑色菜单(汉堡包)图标:

[译]动画矢量图(简单几步就能动起来)

3.创建动画文件

  • 它们指定了 vector 的动画部分
  • 可以将多个动画分别指定给一个 vector drawable的不同的部分
  • vector 不同的部分用 name 标签指定(例如 menu , bottom_container , bottom , stem_container , stem , top_container , top
  • 动画文件根元素既可以是 set 也可以是 objectAnimator
  • 这些文件需要放在res/anim目录下

接下来的代码展现了 top_container 动画,它定义了四个属性, translateXtranslateYscaleX 以及 rotation :

<?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>

4.创建animate-vector drawable文件

  • animated-vector 将所有的内容都联系在一起( vector drawable文件和所有的 animation 文件)
  • 需要将它放在你项目的res/anim目录下
<?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>

需要注意的是:

如果你的 minSdkVersion 小于21(如果大于的话,那我真的不知道你为什么会考虑用 AnimatedVectorDrawableCompat …正常用 AnimatedVectorDrawable 就行了),Android Studio可能会在你的 animated-vector 文件中弹出一个静态检查警告:

[译]动画矢量图(简单几步就能动起来)

不要担心这个警告!如果你的代码没有错误,你的 AnimatedVectorDrawableCompat 会忽略掉它并且能够正常工作。当然如果你不想再看到警告,可以添加 tools:ignore="NewApi"

[译]动画矢量图(简单几步就能动起来)

5.编辑你的build.gradle文件

  • 在你的 build.gradle 文件中,将 vectorDrawables.useSupportLibrary = true 添加进 android 部分的 defaultConfig
  • 你需要这行代码,这样你的 animated-vector 才能兼容API小于 Lollipop版本的系统
android {
 compileSdkVersion 24
 buildToolsVersion "24.0.3"
 defaultConfig {
 applicationId "com.junyuan.wukongnew"
 minSdkVersion 21
 targetSdkVersion 24
 versionCode 1
 versionName "1.0"
 vectorDrawables.useSupportLibrary = true
 }
 ...
}

6.将你的AnimatedVectorDrawableCompat设置到ImageView或者ImageButton

  • 你可以用 app:srcCompat 把它添加进xml文件
<ImageView
 android:id="@+id/iv_animated"
 android:layout_width="48dp"
 android:layout_height="48dp"
 app:srcCompat="@drawable/animated_vector_menu_back"/>
  • 或者通过java代码:
final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(this, R.drawable.animated_vector_menu_back);
 animatedIv.setImageDrawable(avd);

7.在你需要的时候开启动画

  • 获得 AnimatedVectorDrawableCompat 的引用(或者是它的一个实现类– Animatable ),如果你的 AnimatedVectorDrawableCompat 是通过java代码添加的,可以直接使用这个对象的引用(你可以跳过这步):
final Animatable animatable = (Animatable) animatedIv.getDrawable();
  • 开启动画
animatable.start()

好消息和坏消息

让我们先来听听好消息:

你可以很轻松通过 Roman Nurik 的AndroidIconAnimator这个工具(尽管当前它是预览版,但是也足够有用了)实现步骤1-3。它可以将svg文件和你所指定的动画元素转换成 animated-vector drawable文件

有一件很有意思的事情是导出来的来的 animated-vector 文件使用了 aapt 工具的一些非常厉害的功能,导出来的drawable文件包含了全部动画所需的代码(包括 vector drawable和 animation 文件)。就是将步骤1-3的所有文件都包含在一个文件里。

坏消息来了:

AnimatedVectorDrawableCompat 在API小于21时有一些限制:

Chris Banes文章 中指出:

animate vectors 在API小于21的平台上工作时同样有一些限制,当前在这些平台上有一下这几点限制:

路径绘制(PathType evaluator),这被用来从一个路径绘制到另一个路径

路径插值器,这被用来定义一个灵活的插值器(展现成一个路径)以代替系统自动生成的,比如说线性插值器(LinearInterpolator)

按路径移动,这很少能用到,几何图形能在限制路径上来回运动

大致意思就是你可以忘了 pathData 元素的动画 pathData ,我们只能期望谷歌的天才们能研究一个方法将这个功能兼容到低版本的系统上去。

 
标签: 安卓开发
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 安卓中通知功能的具体实现
    安卓中通知功能的具体实现
    通知[Notification]是Android中比较有特色的功能,当某个应用程序希望给用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知实现。使用通知的步骤1、需要一个NotificationManager来获得NotificationManager manager = (NotificationManager
    02-05 安卓开发
  • Android view系统分析-setContentView
    Android view系统分析-setContentView
    第一天上班,列了一下今年要学习的东西。主要就是深入学习Android相关的系统源代码,夯实基础。对于学习Android系统源代码,也没什么大概,就从我们平常使用最基础的东西学起,也就是从view这个切入点开始学习Android的源码,在没分析源码之前,我们有的时候
    02-05 安卓开发
  • 如何进行网络视频截图/获取视频的缩略图
    如何进行网络视频截图/获取视频的缩略图
    小编导读:获取视频的缩略图,截图正在播放的视频某一帧,是在音视频开发中,常遇到的问题。本文是主要用于点播中截图视频,同时还可以获取点播视频的缩略图进行显示,留下一个问题,如下图所示, 如果要获取直播中节目视频缩略图,该怎么做呢?(ps:直播是直
  • Android NDK 层发起 HTTP 请求的问题及解决
    Android NDK 层发起 HTTP 请求的问题及解决
    前言新的一年,大家新年快乐~~鸡年大吉!本次给大家带来何老师的最新文章~虽然何老师还在过节,但依然放心不下广大开发者,在此佳节还未结束之际,给大家带来最新的技术分享~ 事件的起因不说了,总之是需要实现一个 NDK 层的网络请求。为了多端适用,还是选择
  • Android插件化(六): OpenAtlasの改写aapt以防止资源ID冲突
    Android插件化(六): OpenAtlasの改写aapt以防
    引言Android应用程序的编译中,负责资源打包的是aapt,如果不对打包后的资源ID进行控制,就会导致插件中的资源ID冲突。所以,我们需要改写aapt的源码,以达到通过某种方式传递资源ID的Package ID,通过aapt打包时获取到这个Package ID并且应用才插件资源的命名
    02-05 安卓开发
  • Android架构(一)MVP架构在Android中的实践
    Android架构(一)MVP架构在Android中的实践
    为什么要重视程序的架构设计 对程序进行架构设计的原因,归根结底是为了 提高生产力 。通过设计是程序模块化,做到模块内部的 高聚合 和模块之间的 低耦合 (如依赖注入就是低耦合的集中体现)。 这样做的好处是使得程序开发过程中,开发人员主需要专注于一点,
    02-05 安卓开发
  • 安卓逆向系列教程 4.2 分析锁机软件
    安卓逆向系列教程 4.2 分析锁机软件
    安卓逆向系列教程 4.2 分析锁机软件 作者: 飞龙 这个教程中我们要分析一个锁机软件。像这种软件都比较简单,完全可以顺着入口看下去,但我这里还是用关键点来定位。首先这个软件的截图是这样,进入这个界面之后,除非退出模拟器,否则没办法回到桌面。上面那
    02-05 安卓开发
  • Android插件化(二):OpenAtlas插件安装过程分析
    Android插件化(二):OpenAtlas插件安装过程分析
    在前一篇博客 Android插件化(一):OpenAtlas架构以及实现原理概要 中,我们对应Android插件化存在的问题,实现原理,以及目前的实现方案进行了简单的叙述。从这篇开始,我们要深入到OpenAtlas的源码中进行插件安装过程的分析。 插件的安装分为3种:宿主启动时立
    02-05 安卓开发
  • [译] Android API 指南
    [译] Android API 指南
    众所周知,Android开发者有中文网站了,API 指南一眼看去最左侧的菜单都是中文,然而点进去内容还是很多是英文,并没有全部翻译,我这里整理了API 指南的目录,便于查看,如果之前还没有通读,现在可以好好看一遍。注意,如果标题带有英文,说明官方还没有翻
  • 使用FileProvider解决file:// URI引起的FileUriExposedException
    使用FileProvider解决file:// URI引起的FileUri
    问题以下是一段简单的代码,它调用系统的相机app来拍摄照片:void takePhoto(String cameraPhotoPath) {File cameraPhoto = new File(cameraPhotoPath);Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);takePhotoIntent.putExtra(Medi
    02-05 安卓开发
点击排行