android property动画,Android开发者指南-Property动画-Property Animation[原创译文]

Property Animation

版本:Android 4.0 r1 - 22 Mar 2012 0:35

译者注:黄色底色为未决译文

property 动画系统是相当健壮的框架,它几乎可以动画显示任何对象。

你可以定义一个动画来定时改变任何对象的属性值,不论该对象是否在屏幕上显示。 property

动画将以一定的时间间隔修改属性值(对象中的字段值)。

要实现动画显示,你须指定对象的相应属性(比如对象的屏幕位置),以及动画时长、动画时间间隔。

property 动画系统能让你设定以下动画要素:

持续时间:指定动画的持续显示时间。默认的时长是300毫秒。

图像插值方式:指定属性值的变化方式,表示为关于动画已显示时间的函数。

重复次数和方式:指定动画是否循环播放,以及重复的次数。还可以指定动画是否反向播放。可以设为先正向播放再反向回放,如此往复直至达到设定的重复次数。

动画集合:你可以把动画分为多个逻辑组,以便实现同时播放、顺序播放或间隔一段时间再播放。

帧刷新间隔:指定动画帧的刷新频率。默认是每 10

ms刷新一次,但应用程序实际可执行的刷新频率取决于系统整体的繁忙程度,以及系统对定时器的支持程度。

首先,我们通过一个简单例子来回顾一下动画的工作原理。图 1 表明了某对象的 x 属性变化情况,即在屏幕上水平的位置。

动画的持续时间设为 40 ms,移动的距离是 40 个像素点。每隔 10 ms,这是默认的帧刷新率,此对象横向移动 10 个像素点。

在 40 ms 到期后,动画停止,此对象位置横移 40 个像素点。以下是采用线性插值的示例,也即此对象以固定的速度移动。

blog_48d4913001011a1u.html

图 1. 线性动画的示例

你还可以把动画设置为非线性插值方式。图 2 表示,某对象开始时加速移动,结束时减速移动。 此对象仍然是在 40 ms 内移动

40 个像素点,但是速度是非线性变化的。在开始时,此动画加速移动至中间位置,然后再减速移动至终点。 如图 2

所示,开始和结束阶段移动的距离比中间位置要少一些。

blog_48d4913001011a1u.html

图 2. 非线性动画示例

让我们来仔细查看一下 property 动画系统的关键部件在上述动画中的计算过程。图 3 展示了主要类的相互工作方式。

blog_48d4913001011a1u.html

图 3. 动画的计算过程

要启动动画,请创建一个 elapsed

fraction),大小介于0和1之间。 时间比例因子代表动画已完成时间的百分比,0 表示 0%,1 表示

100%。例如,在图 1 中,t = 10 ms 时的时间比例因子应该是 0.25,因为总时间 t = 40 ms。

interpolated

fraction)。插值因子是一个由时间比例因子换算出来的图像显示状态因子。 比如,在图 2 中,t = 10 ms

时,因为动画的加速度较小,插值因子约是 0.15,它小于时间比例因子 0.25。 在图 1

中,插值因子一直保持不变,并与时间比例因子一致。

算完插值因子,

范例 API Demos 中的 com.example.android.apis.animation

包给出了很多 property 动画系统的使用例子。

API 概述

你可以在

表 1. Animator

说明

property

动画的主要计时器引擎,用于计算需动画显示的属性值。包含了计算动画值的所有核心功能、每个动画的计时信息、动画是否循环播放、接收更新事件的侦听器、对自定义类型计算的支持。

让属性动画显示包括两步工作:计算动画属性值、向对象的属性赋值。 用 ValueAnimator 实现动画 章节。

提供一种把动画分组归并的机制,以便组合运行多个动画效果。你可以一起播放多个动画效果,或者错时播放。 详情请参阅用 Animator Set 编排多个动画章节。

evaluator 用于告知 property 动画系统给定属性值的计算方式。根据

表 2. Evaluator

类/接口

说明

计算整数型(int)属性时的缺省

evaluator。

计算浮点数型(float)属性时的缺省

evaluator。

计算十六进制颜色属性时的缺省 evaluator。

一个接口,允许你创建自己的 Evaluator。 如果要动画显示的对象属性类型不是int、float、颜色,你就必须实现

int、float、颜色类型的属性指定一个自定义的

使用 TypeEvaluator章节。

时间 interpolator 定义了动画显示的计算方式,它是一个关于时间的函数。

比如,你可以指定线性播放动画,也即全程匀速播放。或者,你也可以指定为非线性播放,比如一开始加速,而临近结束时减速。 表 3 列出了

使用

Interpolator。

表 3. Interpolator

类/接口

说明

该 interpolator 的速度在开始和结束时较慢,而中间加速变化。

该 interpolator 的速度在开始时较慢,然后加速。

该 interpolator 先把起点往回移一点,再快速播放。

该 interpolator 先把起点往回移一点,再快速播放,待越过终点后再返回至结束值。

该 interpolator 在最后阶段以弹球效果显示

该 interpolator 循环播放给定次数。

该 interpolator 开始时快速播放,然后减速。

该 interpolator 匀速播放。

该 interpolator 快进至超过结束值后返回。

该 interpolator 允许你实现自己的 interpolator。

通过指定一组int、float、颜色值,

ValueAnimatoranimation=ValueAnimator.ofFloat(0f,1f);animation.setDuration(1000);animation.start();

在这段代码中, start()方法。

你也可以按照以下格式指定自定义类型的动画值:

ValueAnimatoranimation=ValueAnimator.ofObject(newMyTypeEvaluator(),startPropertyValue,endPropertyValue);animation.setDuration(1000);animation.start();

在这段代码中, startPropertyValue 至

endPropertyValue之间,应用

MyTypeEvaluator,持续时间

1000 ms,并执行

其实这段代码对某对象是无法实现动画效果的,因为 动画侦听器一节。

ObjectAnimatoranim=ObjectAnimator.ofFloat(foo,"alpha",0f,1f);anim.setDuration(1000);anim.start();

为了保证

动画显示的属性必须带有一个 setter 方法(以骆驼拼写法命名),格式类似 set()。

因为 foo,则需要有一个setFoo()方法。

如果此 setter 方法不存在,你有以下三种选择:

如果你有权限的话,直接在类中增加此 setter 方法。

用你有权修改的封装类来增加此 setter 方法,并让该封装类来接收属性值并传给初始的对象。

如果在调用 values...

参数指定了一个值,那此值将被认定为动画属性的结束值。 这样的话,动画显示的属性必须带有一个 getter 方法,用于获取动画的起始值。

此 getter 方法必须以get()的格式命名。

例如:假设属性名为foo,则需要有一个getFoo()方法。

动画属性的 getter 方法(如果必要的话)和 setter 方法所操作数据的类型必须与 targetObject.setPropName(float)

和 targetObject.getPropName(float):

ObjectAnimator.ofFloat(targetObject,"propName",1f)

根据不同的动画显示对象和属性,也许你需要调用 View 的 动画侦听器一节。

很多时候,你需要在一个动画的开始和结束时播放另一个动画。Android 系统可以让你把多个动画组合为一个

以下例程来自 Bouncing Balls 范例(作了一定简化),它将用以下规则播放

播放 bounceAnim。

同时播放 squashAnim1、squashAnim2、stretchAnim1

和 stretchAnim2。

播放 bounceBackAnim。

播放 fadeAnim。

AnimatorSetbouncer=newAnimatorSet();bouncer.play(bounceAnim).before(squashAnim1);bouncer.play(squashAnim1).with(squashAnim2);bouncer.play(squashAnim1).with(stretchAnim1);bouncer.play(squashAnim1).with(stretchAnim2);bouncer.play(bounceBackAnim).after(stretchAnim2);ValueAnimatorfadeAnim=ObjectAnimator.ofFloat(newBall,"alpha",1f,0f);fadeAnim.setDuration(250);AnimatorSetanimatorSet=newAnimatorSet();animatorSet.play(bouncer).before(fadeAnim);animatorSet.start();

关于使用 animator set 的完整示例,请参阅 API Demo 中的 Bouncing Balls。

在播放过程中,你可以用下列侦听器来监听那些重要的动画事件。

根据不同的动画对象及其属性,你也许需要调用 View 的

ValueAnimatorAnimatorfadeAnim=ObjectAnimator.ofFloat(newBall,"alpha",1f,0f);fadeAnim.setDuration(250);fadeAnim.addListener(newAnimatorListenerAdapter(){publicvoidonAnimationEnd(Animatoranimation){balls.remove(((ObjectAnimator)animation).getTarget());}

与 View 动画一样简单, property 动画系统对 ViewGroup 对象的动画显示提供了支持。

你可以用

APPEARING ——

元素在容器中显现时需要动画显示。

CHANGE_APPEARING ——

由于容器中要显现一个新的元素,其它元素的变化需要动画显示。

DISAPPEARING ——

元素在容器中消失时需要动画显示。

CHANGE_DISAPPEARING

—— 由于容器中某个元素要消失,其它元素的变化需要动画显示。

你可以为这四种事件定义自己的动画方式,以便定制 layout 变化时的外观,也可以只是通知动画系统采用默认的动画方式。

API Demo 中的 LayoutAnimations 示例展示了 layout 变化形式的定义,并设置了 View 的动画方式。

LayoutAnimationsByDefault 及其对应的 layout_animations_by_default.xml layout 资源文件展示了以 XML 格式启用

ViewGroups layout 默认变化形式的方法。 你唯一要做的就是把 ViewGroup 的 android:animateLayoutchanges

属性设为 true。 比如:

此属性设为 true 将会自动把 View 加入和移出 ViewGroup 的过程以动画方式显示,ViewGroup 中其它的

View 同时也会以动画方式进行调整。

如果 Android 系统无法识别需要动画显示的属性值类型,你可以创建自己的 evaluator,实现 int、float和颜色,分别由

publicclassFloatEvaluatorimplementsTypeEvaluator{publicObjectevaluate(floatfraction,ObjectstartValue,ObjectendValue){floatstartFloat=((Number)startValue).floatValue();returnstartFloat+fraction*(((Number)endValue).floatValue()-startFloat);}}

注意: 当 fraction

参数本身就是此插值因子,因此你在计算动画属性值时就不必用到 interpolator 了。

插值器(interpolator)定义了动画过程中属性值的变化规则,它是一个关于时间的函数。

比如,你可以把动画过程设定为线性变化,这意味着它全程都是匀速变化。

或者,你可以设定动画为非线性变化,比如在开始或结束时加速或减速。

动画系统中的 interpolator 会从 Animator 中接收到一个时间比例因子,此因子代表了动画已显示的时间。

interpolator 会根据动画的类型修改此因子。Android 系统在

AccelerateDecelerateInterpolator

publicfloatgetInterpolation(floatinput){return(float)(Math.cos((input+1)*Math.PI)/2.0f)+0.5f;}

LinearInterpolator

publicfloatgetInterpolation(floatinput){returninput;}

下表列出了这些 interpolator 对持续 1000 ms 的动画计算出的近似值:

已显示的时间值 ms

已显示的时间比例因子/插值后因子(线性)

插值后因子 (加速/减速)

0

0

0

200

.2

.1

400

.4

.345

600

.6

.8

800

.8

.9

1000

1

1

如上表所示,

要实例化一个

Keyframekf0=Keyframe.ofFloat(0f,0f);Keyframekf1=Keyframe.ofFloat(.5f,360f);Keyframekf2=Keyframe.ofFloat(1f,0f);PropertyValuesHolderpvhRotation=PropertyValuesHolder.ofKeyframe("rotation",kf0,kf1,kf2);ObjectAnimatorrotationAnim=ObjectAnimator.ofPropertyValuesHolder(target,pvhRotation)rotationAnim.setDuration(5000ms);

关于使用关键帧的完整示例,请参阅 API Demo 中的 MultiPropertyAnimation

property 动画系统可以让 View 对象进行一系列的动画显示,相比 view 动画系统具有更多优势。 view

动画系统通过改变 View 对象的绘制方式来实现动画效果。 因为 View 本身没有给出属性以供控制,所以这是由 View

所在容器来完成处理的。 虽然这样能实现 View 的动画效果,但 View 对象本身并没有变化。

因此会出现这种情况:虽然屏幕上的显示位置已经移动过了,但对象实际仍然停留在原来的位置。 为了消除这一弊病,在 Android 3.0

中给 View 增加了一些新的属性以及相应的 getter、setter 方法。

property 动画系统可以通过修改 View 对象实际的属性值来实现屏幕上的动画效果。此外,当属性值发生变化时,Views

也会自动调用

translationX 和

translationY:这两个属性控制着

View 的屏幕位置坐标变化量,以 layout 容器的左上角为坐标原点。

rotation、rotationX

和 rotationY:这三个属性控制着

2D 旋转角度(rotation属性)和围绕某枢轴点的

3D 旋转角度。

scaleX、scaleY:这两个属性控制着 View

围绕某枢轴点的 2D 缩放比例。

pivotX 和

pivotY:

这两个属性控制着枢轴点的位置,前述的旋转和缩放都是以此点为中心展开的。缺省的枢轴点是 View 对象的中心点。

x 和

y:这是指

View 在容器内的最终位置,等于 View 左上角相对于容器的坐标加上 translationX 和 translationY

后的值。

alpha:表示 View 的

alpha 透明度。缺省值为 1 (不透明),为 0 则表示完全透明(看不见)。

要动画显示 View 对象的某个属性,比如颜色或旋转值,你所有要做的事情就是创建一个 property

animator,并设定对应的 View 属性。比如:

ObjectAnimator.ofFloat(myView,"rotation",0f,360f);

关于创建 animator 的详细信息,请参阅 ValueAnimator 和 ObjectAnimator 章节。

利用一个基础的 x 和 y 属性的同时变化。

多个 ObjectAnimator 对象

ObjectAnimatoranimX=ObjectAnimator.ofFloat(myView,"x",50f);ObjectAnimatoranimY=ObjectAnimator.ofFloat(myView,"y",100f);AnimatorSetanimSetXY=newAnimatorSet();animSetXY.playTogether(animX,animY);animSetXY.start();

单个 ObjectAnimator

PropertyValuesHolderpvhX=PropertyValuesHolder.ofFloat("x",50f);PropertyValuesHolderpvhY=PropertyValuesHolder.ofFloat("y",100f);ObjectAnimator.ofPropertyValuesHolder(myView,pvhX,pvyY).start();

ViewPropertyAnimator

myView.animate().x(50f).y(100f);

关于 blog post 相关内容。

property 动画系统允许你用 XML 声明 property 动画,而不需要编写代码来实现。 通过 XML

定义的方式,你可以方便地在多个 activity 中复用动画资源,并且更容易编排动画顺序。

为了把采用新增 property 动画 API与采用以前 view animation 框架的动画文件区分开来,自 Android 3.1 开始,你应该把 property 动画

XML 文件保存到res/animator/目录下(而不是res/anim/目录)。

目录名animator是可以修改的,但如果你要用

Eclipse ADT(ADT 11.0.0+) 插件作为 layout 编辑工具,那就不能动了。 因为 ADT

只会搜索res/animator/目录下的动画资源。

以下列出了可用 XML 标记声明的 property 动画类:

以下例子顺序播放两组动画,第一组动画内嵌入了两个对象的动画:

为了播放这个动画,你必须用代码把 XML 资源置入

AnimatorSetset=(AnimatorSet)AnimatorInflater.loadAnimator(myContext,R.anim.property_animator);set.setTarget(myObject);set.start();

关于定义 property 的 XML 语法,请参阅动画资源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值