Android动画Property Animation入门

介绍

Android动画分为3类,Property Animation、View Animation、Drawabe Animation。

官方推荐使用:Property Animator。因此我目前也只看了Property Animation,这里也暂时只介绍Property Animation。

Property Animation主要设计到一下几个方面:Animator类,Interpolator(译作插值)类,TypeEvaluator,AnimatorListener,在xml中定义动画。

下面本文会分别对这些类简要介绍。

Animator类

Animator是基类,有3个主要的子类:ValueAnimator,ObjectAnimator,AnimatorSet。

ValueAnimator

一般不用这个类。最基本的用法如下:

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 10f);<span style="white-space:pre">	</span>// 创建一个动画
valueAnimator.setDuration(1000ms);<span style="white-space:pre">				</span>// 设置时长1000ms。默认是300ms
valueAnimator.start();	<span style="white-space:pre">					</span>// 开始动画

这个动画会在1000ms间,计算0到1之间的值。当然这个动画显而易见没有任何用。

ValueAnimator最常用的用法是搭配ValueAnimator.AnimatorUpdateListener使用,更新想要操作的view的某些属性。如下:

final TextView textView = (TextView) findViewById(R.id.activity_main_text_view_hello);

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 4f);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float value = (Float)animation.getAnimatedValue();<span style="white-space:pre">	</span>// 获取animator计算的值
        textView.setScaleX(value);
        textView.setScaleY(value);
    }
});

valueAnimator.setDuration(8000);
valueAnimator.start();

一般是在这样便有了一点实用性,这会把textView在4s之内放大,从0倍到4倍。(没录像。自己试试。)

需要注意的是,用ofInt来构造valueAnimator的时候,播放的动画并不是连贯的。因为getAnimatedValue返回的是int值,setScaleX/Y也就只能成倍放大动画,造成动画不连贯。

ObjectAnimator

这个类是ValueAnimator的子类,也是非常常用的类。

一般用法如下:

ImageView imageView = (ImageView) findViewById(R.id.activity_main_image_view_round);
<pre name="code" class="java">// 指定渲染的属性是alpha。也可以指定其他的,比如rotation。
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f); // 指定要操作的property

 
objectAnimator.setDuration(8000);
objectAnimator.start();

对于要操作的property,其对象一定要有一个setPropertyName方法。比如上面的alpha,View类有一个setAlpha方法。

对于ValueAnimator和ObjectAnimator,我们还可以指定动画重复的次数和模式(重播,倒播)。

// ...
objectAnimator.setRepeatCount(2);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.start();

AnimatorSet

顾名思义,这个类是一个animator的集合类。主要是将几个动画按一定的次序播放,比如:同时播放,顺序播放。AnimatorSet可以嵌套AnimatorSet。

一般用法如下:

ImageView rectImageView = (ImageView) findViewById(R.id.activity_main_image_view_rect);
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rectImageView, "alpha", 0f, 1f);
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(rectImageView, "rotation", 0f, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(alphaAnimator, rotationAnimator);
animatorSet.setDuration(8000);
animatorSet.start();

上面指定两个动画同时播放。要先后播放可以用:

animatorSet.playSequentially(alphaAnimator, <span style="font-family: Arial, Helvetica, sans-serif;">rotationAnimator);</span>
需要注意的是,AnimatorSet是不能设置repeatCount和repeatMode的。只能在AnimatorSet的子ValueAnimator中设置动画。

其他一些用法请查看文档。

ViewPropertyAnimator

上面可以看到,当一个View同时有几个属性要渲染的时候,就要创建几个ObjectAnimator。一两个还可以接受,5、6个就未免太多。ViewPropertyAnimator就是因此而来,且只能用在View上。ViewProperty还针对View专门进行了优化(这里我抄的官方的哈)。官方是如此介绍ViewPropertyAnimator的:

This class enables automatic and optimized animation of select properties on View objects. If only one or two properties on a View object are being animated, then using an ObjectAnimator is fine; the property setters called by ObjectAnimator are well equipped to do the right thing to set the property and invalidate the view appropriately. But if several properties are animated simultaneously, or if you just want a more convenient syntax to animate a specific property, then ViewPropertyAnimator might be more well-suited to the task.
如我们可以写如下一个ViewPropertyAnimator:
rectImageView2.animate().setDuration(8000).alpha(1f).rotation(90f).scaleX(2f).scaleY(2f);
很简洁啊。这要是用AnimatorSet来写,得要有4个ObjectAnimator。
还有一些其他的东西,比如KeyFrame我暂时还没关注。具体看官方文档吧:http://developer.android.com/intl/zh-cn/guide/topics/graphics/prop-animation.html

Interpolator

Interpolator我译作插值。用法呢,就是改变动画表现的速度。比如匀速播放、加速播放、前后加速中间匀速。

Interpolator都实现了TimeInterpolator,常用的Interpolator有:LinearInterpolator,AccelerateInterpolator。默认的是AccelerateDecelerateInterpolator。还有其他一些Interpolator,可以去看看官方文档。

下面将上面的AnimatorSet加速播放:

animatorSet.setInterpolator(new AccelerateInterpolator());
animatorSet.start();

TypeEvaluator

像上面的"alpha", "rotation"这些属性,当按照默认的Interpolator来渲染的时候,都可以平滑的渲染。你看,透明度从0慢慢变成1。rotation从0度变到360.这样不管是匀速还是变速,动画的效果都是很平滑的。但是有一些其他属性,比如颜色,如果颜色从一个值,慢慢变到另一个值,那么动画的效果肯定不平滑。如下:

ObjectAnimator alphaAnimator = ObjectAnimator.ofInt(rectImageView, "backgroundColor",
        getResources().getColor(android.R.color.holo_blue_bright), getResources().getColor(android.R.color.holo_red_light));
alphaAnimator.setDuration(8000);
alphaAnimator.start();	

这个动画播放出来就是一闪一闪的。这显然不是我们的预期。

为什么会出现这样的问题呢,因为颜色这一属性,系统认为是int类型了,在播放动画的时候,计算的颜色的值的方法和计算int值一样,就造成,颜色缓慢从起始值变化到结束值,这样的值代表的颜色,不是我们所预期的,或者说让动画看起来一闪一闪的。

这时,我们只需要加入下面这么一行代码,就可以了:

alphaAnimator.setEvaluator(new ArgbEvaluator());
这样告诉系统,我们渲染的类型的颜色类型。你也可以自己实现TypeEvaluator,按照自己的目的去渲染。

AnimatorListener

这个和view listener的目的都是一的样,监听某个重要的事件,然后执行对应的操作。

比如,在动画每次结束后,你要把视图隐藏,抑或再来一遍。如下:

alphaAnimator.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        rectImageView.setVisibility(View.GONE);
    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
});
alphaAnimator.start();
一个常用的类是AnimatorListenerAdapter,这个类实现了AnimatorListener。默认实现都是空,我们只需覆盖我们需要的事件。用在上面,代码就变成下面这样子了:

alphaAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        rectImageView.setVisibility(View.GONE);
    }
});
alphaAnimator.start();

还有一个AnimatorUpdateListener,在前面已经用过一次,大概的用法也差不多是那样。

在xml中定义动画

ObjectAnimator、ValueAnimator、AnimatorSet在xml中分别对应这3个tag:objectAnimator、animator、set。

下面定义了一个AnimatorSet:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:propertyName="alpha"
        android:valueFrom="0f"
        android:valueTo="1f"
        android:duration="3000"
        />
    <objectAnimator
        android:propertyName="rotation"
        android:valueFrom="0f"
        android:valueTo="359.9f"
        android:duration="3000"
        />
    <objectAnimator
        android:propertyName="scaleX"
        android:valueFrom="0f"
        android:valueTo="2f"
        android:duration="3000"
        />
    <objectAnimator
        android:propertyName="scaleY"
        android:valueFrom="0f"
        android:valueTo="2f"
        android:duration="3000"
        />

</set>

这个set包含了4个ObjectAnimator,它们分别是逐渐展示透明色,旋转,缩放X,缩放Y。这4个ObjectAnimator同时播放。播放时长都为3000ms。

正如用LayoutInflater取出用xml定义的layout,我们也可以用AnimatorInflater取出用xml定义的动画,然后为取出的动画设置操作的对象,最后播放动画。如下:

ImageView rectImageView2 = (ImageView) findViewById(R.id.activity_main_image_view_rect2);
AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_rotate);
animatorSet.setTarget(rectImageView2);
animatorSet.start();

结语

终于写完了。写的不对的地方,还请大家及时指正。还有重点,需要添加的地方,也请大家指出,我补充在博文里。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值