Property Animation

Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,其改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性都改变了, 是这个对象属性的改变。而且Property Animation不止可以应用于View,还可以应用于 任何对象。

在Property Animation中,你可以对动画应用以下属性:

Duration:动画的持续时间

Time interpolation:应用动画的属性的属性值如何改变,即根据动画的进行时间其属性值的计算方式

Repeat Country and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放

Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移

Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最中刷新间隔还受系统繁忙程序与硬件的影响

Property Animation的工作方式

对于下图的动画,这个对象的X坐标在40ms内从0移动到40 pixel.按默认的10ms刷新一次,这个对象会移动4次,每次移动40/4=10pixel。

animation-linear

也可以改变属性值的改变方法,即设置不同的interpolation,在下图中运动速度先逐渐增大再逐渐减小

animation-nonlinear

下图显示了与上述动画相关的关键对象

valueanimator

ValueAnimator包含的应用动画的属性的开始值,结束值,持续时间的属性。

ValueAnimator还封装了一个TimeInterpolator,TimeInterpolator定义了属性值在开始值与结束值之间的插值方法。

ValueAnimator还封装了一个TypeAnimator,也跟属性值的计算有关。

ValueAnimator根据动画已进行的时间跟总时间的比计算出一个时间因子(0~1),然后根据TimeInterpolator出另一个因子,最后TypeAnimator通过这个因子计算出属性值,如上例中10ms时:

在时间因子a=10ms/40ms=0.25

经相应的插值方法后(inteplator)的插值因子:大约为0.15(计算公式为:(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; input即为时间因子)

最后计算出在10ms时的属性值:0.15*(40-0)=6pixel。

ValueAnimation

包含中Property Animation动画的所有核心功能,如动画时间,开始结束属性值,相应时间属性值计算方法等。就用Property Animation有两步,一、计算属性值;二、将属性值应用于对象。ValuAnimiation只完成了第一步,如果要完成第二步,需要 Animator.AnimatorListener接口

ObjectAnimator

ValueAnimator的子类,要指定一个对象及该对象的一个属性,当属性值计算完成时自动应用于该对象的相应属性,即完成了Property Animation的两步。一般都会用ObjectAnimator,但其有一定限制,如需要应用玩的对象有accessor方法(如 setColor)。

AnimatorSet

提供了一个把多个动画组合成一个组的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。

Evalutors

根据Animator中的start time,end time,duration等计算属性值,android提供了以下几个evalutor:

IntEvalutor:属性值为int;

FloatEvalutor:属性值为float;

ArgbEvalutor:属性值为十六进制颜色值;

TypeEvalutor:一个接口,你可以通过实现该接口自定义Evalutor。

自定义TypeEvalutor很简单,只需要实现一个方法,如FloatEvalutor的定义:

1public class FloatEvaluator implements TypeEvaluator {
2public Object evaluate(float fraction, Object startValue, Object endValue) {
3float startFloat = ((Number) startValue).floatValue();
4return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
5}
6}

根据动画执行的时间跟应用的Interplator,会计算出一个0~1之间的因子,即evalute函数中的fraction参数,通过上述FloatEvaluator应该很好看出其意思。

Time Interplator

time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。

AccelerateInterpolator开始时慢,中间加速
DecelerateInterpolator开始时快然后减速
AccelerateDecelerateInterolator开始结束时慢,中间加速
AnticipateInterpolator先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator值在[-2*from-to,to]这间循环指定次数
LinearInterpolator线性均匀改变
OvershottInterpolator最后超出目的值然后缓慢改变到目的值
TimeInterpolator一个接口,允许你自定义interpolator

ValueAnimator用法

01ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
02animation.setDuration(1000);
03animation.addUpdateListener(new AnimatorUpdateListener() {
04@Override
05public void onAnimationUpdate(ValueAnimator animation) {
06Log.i("update", ((Float)animation.getAnimatedValue()).toString());
07}
08});
09animation.setInterpolator(new CycleInterpolator(3));
10animation.start();

ObjectAnimator用法

01tv=(TextView)findViewById(R.id.textview1);
02btn=(Button)findViewById(R.id.button1);
03btn.setOnClickListener(new OnClickListener() {
04@Override
05public void onClick(View v) {
06ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
07oa.setDuration(3000);
08oa.start();
09}
10});

要想使用ObjectAnimator,应该满足以下条件:

想通过ObjectAnimator应用动画的属性就能有一个setter函数:set<PropertyName>(双峰命名法)

在上面的例子只像ofFloat类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数你只设置了一个的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:get<PropertyName>

如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。

如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。

根据应用动画的对象或属性的不同,可能需要在onAnimationUpdate函数中调用invalidate()函数刷新视图。

通过AnimationSet应用多个动画

以下例子同时应用5个动画:

播放anim1;

同时播放anim2,anim3,anim4;

播放anim5。

1AnimatorSet bouncer = new AnimatorSet();
2bouncer.play(anim1).before(anim2);
3bouncer.play(anim2).with(anim3);
4bouncer.play(anim2).with(anim4)
5bouncer.play(anim5).after(amin2);
6animatorSet.start();
Animation Listeners

Animator.AnimatorListener

onAnimationStart()

onAnimationEnd()

onAnimationRepeat()

onAnimationCancel

ValueAnimator.AnimatorUpdateListener

onAnimationUpdate():通过监听这个事件在属性的值更新时执行相应的操作,对于ValueAnimator要监听此事件执行相应的动作,否则Animation无意义,在ObjectAnimator(继承自 ValueAnimator)中会自动更新属性,如无必要不必监听。在函数中会传递一个ValueAnimator参数,通过此参数的 getAnimatedValue()取得当前动画属性值。

可以继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作,这个类对AnimatorListener中的函数都定义了一个空函数体,这样我们就只用定义想监听的事件而不用实现每个函数却只定义一空函数体。

1ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
2oa.setDuration(3000);
3oa.addListener(new AnimatorListenerAdapter(){
4public void on AnimationEnd(Animator animation){
5Log.i("Animation","end");
6}
7});
8oa.start();

Animating Layout Changes to ViewGroups
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值