每个人都有一定的理想,这种理想决定着他的努力和判断的方向。就在这个意义上,我从来不把安逸和快乐看作生活目的的本身——这种伦理基础,我叫它猪栏的理想。——爱因斯坦

一、摘要

Property Animation(属性动画)是一个非常强大的框架,它允许你让任何对象都实现动画效果。 因为不管一个对象是否出现屏幕中,你都可以随时去改变它的属性,而属性动画正是通过在某个时间点改变对象的属性实现动画效果的。Property Animation是在Android 3.0(API 11)之后推出的,以其具有高扩展性,解决了一些View Animation所不能解决的问题,所以,对于Android开发者来说,Property Animation是一个非常重要的知识点。

本文主要对ValueAnimator做介绍,如果大家有兴趣,可以继续阅读本动画系列其他相关文章,作者也在不断更新完善相关内容,希望大家可以指出有误之处。

Android基础夯实--重温动画(一)之Tween Animation

Android基础夯实--重温动画(二)之Frame Animation

Android基础夯实--重温动画(四)之属性动画 ValueAnimator详解

1.1 背景

由于Tween Animation(补间动画)只能实现简单的四种的动画(alpha、scale、rotate、translate),要想实现比较复杂的动画就难以满足需求,而Frame Animation只是改变了View对象绘制的背景,而没有改变View对象本身。所以当我们想使用View Animation实现一些特殊的动画效果时,就比较困难了。例如,当我们想改变一个控件的背景颜色时,视图动画并不能实现;当我们想设置一个按钮在位置转换之后,仍然保持点击事件,视图动画也不能实现。在这个背景之下,属性动画应运而生。

1.2 区别

说了这么多,那么视图动画和属性动画到底有什么区别呢?

首先,在直观上,属性动画是区别于视图动画的:

(1) 时间不一样: 视图动画是从API LEVEL 1就引入了;而属性动画是从API LEVEL 11之后才引入。

(2) 名字不一样: 视图动画的Tween Animation命名为xxxAnimation、Frame Animation命名为AnimationDrawable;而属性动画,则命名为xxxAnimator。

(3) 包名不一样: 视图动画的Tween Animation在包android.view.animation下,而Property Animation在包android.animation中。

其次,从根本上,我们可以总结出视图动画和属性动画的两个主要区别:

(1) 视图动画只能改变View的位置或者视觉效果,并不能改变其属性。例如:使用Tween Animation对Button实现位移变换后位置改变,但是点击Button最后停留位置时,并不能响应点击事件。怎么理解呢,举个例子:

由上图可知,我们给TextView设置了点击事件,当我们分别使用Tween Animation和Property Animation移动TextView时,当使用Tween Animation位移TextView后,它的点击事件无效,当使用Property Animation移动TextView后,它的点击事件仍然有效。由此可见,视图动画并不能改变View的属性,而属性动画可以。

(2) 视图动画作用对象只限制为View,而属性动画作用对象不限为View,而是任何对象。例如:属性动画可以改变颜色值而视图动画做不到。同样举个例子:

由上图可以看到,当我们需要对一个对象的颜色值进行改变时,视图动画并不能实现这个效果,上图是通过属性动画来实现的,由此可以推测出,视图动画只能对View起作用,而属性动画作用的不只是View,而是对象。

1.3 建议

虽然Property Animation的优点要多于View Animation,但是View Animaiton可以让我们花更少的时间和更少的代码去实现,所以如果View Animation已经足以满足我们的日常需要,那么我们就没必要使用Property Animation了,当然,如果我们都涉及到的话,同时使用View Animation和Property Animation可能是更有效的办法。

如果你想了解更权威的解释,可以查看官方文档:Property Animation

本文主要对Property Animation做介绍,如果大家有兴趣,可以继续阅读本动画系列其他相关文章:

Android基础夯实--重温动画(一)之Tween Animation

Android基础夯实--重温动画(二)之Frame Animation

二、工作原理

在讲述具体Property Animation相关API之前,我想先给大家讲一下属性动画是如何工作的。下面通过一个例子,这是Android开发指南上面的一个例子,我觉得非常好理解,这里就搬过来了。

首先,我们来看一个例子。如下图描述的是一个对象在它的x方向上进行水平运动的动画(规定右方向为正轴),当然我们可以对应成手机屏幕上的位置。这个动画的时长为40ms,对象在x正方向运动了40个像素,在每个10ms内,这个对象就往x正方向运动10个像素,在第40ms时,这个动画停在了x方向上的40像素,这是一个水平匀速运动的例子。

当然,我们也可以给动画定义一个具有不匀速插值器(Interpolation),是它运动过程为不匀速。
如下图也是一个对象的运动过程,但是它并不是匀速运动,而是开始加速,在结束前减速。这个对象仍然是在40秒内运动了40个像素的距离,但是这个过程是不匀速的,它从开始到中间位置进行了加速运动,在中间位置到结束位置则进行了减速运动。

从上面两个例子可以看到,当我们想要一个对象实现一定的动画效果时,我们可以通过对应的图,还有相关的数据,和相关数据伴随时间的变化来描述该动画过程,但是我们的属性动画的内部是如何像我们这样来描述自身的变化过程的呢?以ValueAnimator为例,我们来看一下属性动画的重要组成部分,如下图所示。

ValueAnimator是属性动画最基础的一个类(我们暂且不深究它,反正它能帮助我们实现图2的先加速后减速的过程)。首先它在内部封装了非常重要的两个接口,第一个就是TimeInterpolator,另一个是TypeEvaluator。大家在心里必须先有个概念,在所有的属性动画里面,都拥有这两个东西。

TimeInterpolator是什么呢?非常简单,就是我们上面所说的插值器,简单来说就是描述对象加速度的一个东西,再简单一点来说就是描述速度变化的一个东西。

TypeEvaluator又是什么呢?大家可以理解为求值器,它是根据上面的插值器来计算对象属性具体值的这么一个东西。

ValueAnimator在执行之前,首先会把时间分为百分数,由0~1,如上图动画过程为40ms,那么在10ms时,时间因子为0.25,在40ms时,时间因子为1。

在计算完时间因子之后,ValueAnimator会调用TimeInterpolator来进行计算插值因子,在图2对应为速度,对应10ms时的速度我们知道会比20ms时的速度会低;而图1中,每一个时刻的速度都一样,所以TimeInterpolator大概是做这么一件事情。

在TimeInterpolator计算完了之后,那么我们的TypeEvaluator就要起作用了,因为上图对应的是对象的位置变化,所以TypeEvaluator为IntEvaluator。这个TypeEvaluator主要是根据TimeInterpolator提供的插值因子(速度),还有startPropertyValue(开始时间)和endPropertyValue(结束时间),计算出某个时刻的属性值(位移),如图2,假如t=10ms时刻,TimeInterpolator给我们返回值为0.15,那么这时在x方向上的位移为0.15 * (40 - 0) = 6。

而这种计算过程在动画执行时间(duration)内是不断重复的,因为ValueAnimator有一个叫做AnimatorUpdateListener的监听器,它会跟踪动画的每一个时刻,所以我们可以在里面进行不断的计算,通过getAnimatedValue()来获取最新值,直到动画结束。

一个属性动画的执行过程大概如上,相信大家已经对属性动画有了基本的了解,那么我们下面根据API来对属性动画进行详细讲解。

三、API概况

前面我们说到,属性动画机制所有相关的类都位于android.animation包之下,所以大家有需要可以到官方文档中进行查阅。下面几个表格是属性动画中常用的类,首先给大家大概介绍。

表格1. Animators

Class Description
ValueAnimator 针对值变化的Animator。
ObjectAnimator 针对Object变化的Animator。
AnimatorSet 运行一组Animator的集合。

Animator类作为属性动画的基类,它是一个抽象类,它提供了实现动画的基本架构,但是我们不能直接使用它,因为它只是提供了最基本的的实现动画的方法,只有让它的子类继承它并进行相应扩展之后,我们才会使用它实现动画。在属性动画中,Animator包括了ValueAnimator、ObjectAnimator和AnimatorSet三个子类,我们分别来介绍一下这三个类。

表格2. Evaluators

Class Description
TypeEvaluator 求值器接口,所有求值器必须实现该接口。
IntEvaluator 计算Int类型的求值器。
FloatEvaluator 计算Float类型的求值器。
ArgbEvaluator 计算颜色值类型的求值器。

API中为我们提供了求值器的接口TypeEvaluator,当然还要它的实现类,例如IntEvaluator、FloatEvaluator、ArgbEvaluator、 IntArrayEvaluator、FloatArrayEvaluator等,它们都是根据fraction因子来计算出对应的属性值,当然我们也可以自定义自己的Evaluator。

表格3. Interpolators

Class Description
TimeInterpolator Animator的插值器接口。

TimeInterpolator作为属性动画的插值器接口,我们都知道在View Animation中有很多插值器,例如AccelerateDecelerateInterpolator(前后减速,中间加速)、AccelerateInterpolator(先慢后加速)等插值器,在属性动画中我们同样可以使用这些插值器,这里就不详细列出来了,不了解的同学可以看我之前的文章:Android基础夯实--重温动画(一)之Tween Animation。当然,我们也可以自定义自己的Interpolator。

四、结语

由于文章篇幅过长,不利于大家阅读,所以这篇文章首先给大家介绍属性动画这个概念,相信通过例子和文字的介绍,大家也已经对属性动画有所了解,那么接下来,我就会给大家详细讲解属性动画中的每一个知识点,当然,也会分多篇文章进行分析,如果你已经准备好,请继续阅读Android基础夯实--重温动画(四)之属性动画 ValueAnimator详解

Android基础夯实--重温动画(三)之初识Property Animation的更多相关文章

  1. Android基础夯实--重温动画(二)之Frame Animation

    心灵鸡汤:天下事有难易乎,为之,则难者亦易矣:不为,则易者亦难矣. 摘要 当你已经掌握了Tween Animation之后,再来看Frame Animation,你就会顿悟,喔,原来Frame Ani ...

  2. Android基础夯实--重温动画(五)之属性动画 ObjectAnimator详解

    只有一种真正的英雄主义 一.摘要 ObjectAnimator是ValueAnimator的子类,它和ValueAnimator一样,同样具有计算属性值的功能,但对比ValueAnimator,它会更 ...

  3. Android基础夯实--重温动画(四)之属性动画 ValueAnimator详解

    宝剑锋从磨砺出,梅花香自苦寒来:千淘万漉虽辛苦,吹尽狂沙始到金: 长风破浪会有时,直挂云帆济沧海 一.摘要 Animator类作为属性动画的基类,它是一个抽象类,它提供了实现动画的基本架构,但是我们不 ...

  4. Android基础夯实--重温动画(一)之Tween Animation

    心灵鸡汤:真正成功的人生,不在于成就的大小,而在于你是否努力地去实现自我,喊出自己的声音,走出属于自己的道路. 摘要 不积跬步,无以至千里:不积小流,无以成江海.学习任何东西我们都离不开扎实的基础知识 ...

  5. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  6. Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  7. Android(java)学习笔记208:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  8. Android UI开发第四十三篇——使用Property Animation实现墨迹天气3.0引导界面及动画实现

    前面写过<墨迹天气3.0引导界面及动画实现>,里面完美实现了动画效果,那一篇文章使用的View Animation,这一篇文章使用的Property Animation实现.Propert ...

  9. android 动画基础绘——帧动画(三)

    前言 这篇介绍帧动画. 什么是帧动画? 帧动画,非常好理解.就是轮播,比如我们看电视,其实就是一张一张播放过去的. 正文 <?xml version="1.0" encodi ...

随机推荐

  1. centos7 64位系统jdbc连接oracle报错问题

    这两天发生了一个错误,记录下来. 报错如下: ### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could n ...

  2. AngularJS 基础入门(指令篇)

    一.介绍 AngularJS 是google 开发人员设计的一个前端开发框架,它是由是由javascript 编写的一个JS框架.通常它是用来在静态网页构建动态应用不足而设计的. AngularJS特 ...

  3. ExtJs布局中,控件如何水平居中?

    如此即可,有图有代码有j8: var formGridHead = Ext.create('Ext.form.Panel', { id: 'MyGridHead', region: 'north', ...

  4. 注册中心Eureka页面添加用户认证

    我们需要登录即可访问到Eureka服务,这样其实是不安全的 为Eureka添加用户认证. 第一步,为itcast-microservice-eureka添加安全认证依赖: 第二步,增加applicat ...

  5. Magic Grid ComboBox JQuery 版

    在MagicCombo组件中嵌入Grid,以支持分页查找和跨页选取 ​ 1. ​2. [代码][JavaScript]单选示例代码     <script type="text/jav ...

  6. VC++6.0不兼容win10导致调试按钮不能正常作用得解决方案

    win10正式版是一个全新的操作系统,所以我们在系统中运行类似VC6这类旧软件时,难免会遇到一些问题. 比如,现在有些用户在win10环境下运行VC6时,按F10.F11进行单步调试, 会出现:Unh ...

  7. bzoj 4818: [Sdoi2017]序列计数【容斥原理+dp+矩阵乘法】

    被空间卡的好惨啊---- 参考:http://blog.csdn.net/coldef/article/details/70305596 容斥,\( ans=ans_{没有限制}-ans{没有质数} ...

  8. 洛谷P4331 [BOI2004]Sequence 数字序列(左偏树)

    传送门 感觉……不是很看得懂题解在说什么? 我们先把原数列$a_i-=i$,那么本来要求递增序列,现在只需要求一个非严格递增的就行了(可以看做最后每个$b_i+=i$,那么非严格递增会变为递增) 如果 ...

  9. 【SpringCloud构建微服务系列】Feign的使用详解

    一.简介 在微服务中,服务消费者需要请求服务生产者的接口进行消费,可以使用SpringBoot自带的RestTemplate或者HttpClient实现,但是都过于麻烦. 这时,就可以使用Feign了 ...

  10. 进击的Python【第十一章】:消息队列介绍、RabbitMQ&Redis的重点介绍与简单应用

    消息队列介绍.RabbitMQ.Redis 一.什么是消息队列 这个概念我们百度Google能查到一大堆文章,所以我就通俗的讲下消息队列的基本思路. 还记得原来写过Queue的文章,不管是线程queu ...