Android动画

目录

1. 补间动画

(1) 透明度渐变动画(AlphaAnination)

(2) 旋转动画(RotateAnimation)

(3) 缩放动画(ScaleAnimation)

(4) 平移动画(TranslateAnimation) 

(5) 控件执行补间动画

(6) 在代码中实现补间动画

2. 逐帧动画

3. 属性动画

(1) Animator类

① 使用ValueAnimator类添加动画效果

② 使用ObjectAnimator类添加动画效果

③ 使用AnimatorSet类添加多个动画效果

(2) 评估程序

(3) 插值器 Interpolator

(4) 动画监听器

① Animator.AnimatorListener

② ValueAnimator.AnimatorUpdateListener

4. 属性动画总结


在Android手机上,我们通常可以看到一些动画效果比较炫酷的App界面,这些动画效果是如何实现的呢?为了实现这些动画效果,Android给我们提供了3种动画模式,分是补间动画逐帧动画属性动画

1. 补间动画

补间(Tween)动画是通过对View进行一系列的动画操作来实现动画效果,其中动画操作包括平移、缩放、旋转、改变透明度等。补间动画的效果可以通过XML文件的方式实现,也可以通过代码方式某进一般最常用的是通过XML文件的方式实现View的动画效果存于res/anim文件夹中(需创建)在Andraid中,补间动画包括透明度渐变动画(AlphaAnimation)、旋转动画(RotateAnimation)、缩放动画(ScaleAnination)、平移动画(TranslateAnimation)

(1) 透明度渐变动画(AlphaAnination)

透明度渐变动画主要通过指定动画开始时View的透明度、结束时Viev的透明度及动画持续时间来实现。在XML文件中定义透明度渐变动画具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:interpolator="@android:anim/linear_interpolator"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="1000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0"/>
</set>

上述在码定义了一个透明度渐变动画,这个动画效果可以使View从完全不透明到透明,动画持续时间为1秒,并且动画可以反向无限循环。

属性及功能:

  • android:interpolator:用于控制动画的变化速度,可设置的值有@android:anim/linear_interpolator(匀速改变)@android:anim/accelerateinterpolator(开始慢,后来加速)等。
  • android:repeatMode:用于指定动画重复的方式,可设置的值有reverse(反向),restart(重新开始)
  • android:repeatCount:用于指定动画重复的次数,该属性的值可以为正整数;也可以为infinite(无限循环)
  • android:duration:用于指定动画播放时长
  • andraid:fromAlpha:用于指定动画开始时View的透明度,0.0为完全透明,1.0为不透明android:toAlpha:用于指定动画结束时View的透明度,0.0为完全透明,1.0为不透明

上述属性中的android:interpolator、android:repeatMode、android:repeatCount、android:duration属性在其他补间动画中也可使用。

(2) 旋转动画(RotateAnimation)

旋转动画是通过对View指定动画开始时的旋转角度,结束时的旋转角度及动画播放时长来实现的,在XML文件中定义旋转动画的具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="1000"/>
</set>

上述代码定义了一个旋转动画,旋转的角度从0°到360°,动画的持续时间为1秒,并且该动画可以反向无限循环。

属性及功能:

  • android:fromDegrees:指定View在主动画开始时的角度
  • android:toDegrees:指定view在动画结束时的角度
  • android:pivotX:指定旋转点的 坐标
  • android:pivoty:指定旋转点的Y坐标

android:peivotX和android:pivotY的值可以是整数、百分数(小数)、百分数p(字母p表示parent),例如5050%50%p。android:pivotX为例,为50时表示在当前View左上角的x轴坐标加上50px,为50%时表示在当前View左上角的x轴坐标加上View自己宽度的50%,为50%p时表示当前View左上角X轴坐标加上父控件宽度的50%。

(3) 缩放动画(ScaleAnimation)

缩放动画是通过对动画指定开始时的编故系数、结束时的放系数及动画持续时长来实现的。在XML文件中定义缩放动画的具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="0.5"
        android:toYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="3000"/>
</set>

上述代码定义了一个缩放动画,以View控件的中心位置为缩放点,在X轴和Y轴分别缩小50%持续3秒,并反向无限循环。

属性及功能:

  • android:fromXScale:指定动画开始时X轴上的缩放系数,值为1.0表示不变化
  • android:fromYScale:指定动画开始时Y轴上的缩放系数,值为1.0表示不变化
  • android:toXScale:指定动画结束时X轴上的缩放系数,值为1.0表示不变化
  • android:toYScale:指定动画结束时Y轴上的缩放系教,值为1.0表示不变化
  • android:pivotX:指定缩放点的X坐标
  • android:pivotY:指定缩放点的Y坐标

(4) 平移动画(TranslateAnimation

平移动画是通过指定动画的开始位置、结束位置及动画持续时长来实现的。在XML文件中定义平移动画的具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0.0"
        android:fromYDelta="0.0"
        android:toXDelta="100"
        android:toYDelta="0.0"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        android:duration="3000"/>
</set>

上述代码定义了一个平移动画,该动画的起始位置为(0.0,0.0),结束位置为(100,0.0),持续时间为4秒,并且该动画反向无限循环,其中(0.0,0.0)表示View左上角的坐标,并不是屏幕像素的坐标。 

属性及功能:

  • android:fromXDelta:指定动画开始时View的X轴坐标
  • android:fromYDelta:指定动画开始时View的Y轴坐标
  • android:toXDelta:指定动画结束时View的X轴坐标
  • android:toYDelta:指定动画结束时View的Y轴坐标

(5) 控件执行补间动画

Animation animation=AnimationUtils.load Animation(MainActivity.this,R.anim.animationfile);
imageView.startAnimation(animation);

补间动画XML文件放置于res/anim文件夹中(需自创建)
根标签为set

(6) 在代码中实现补间动画

补间动画不仅可以在XML中定义,也可以在代码中定义。在代码中定义千种补间效果时,需要用到AlphaAnimation类RotateAnimation类ScaleAnimation类TranslateAnimation类,这4个类分别用于实现透明度渐变动画、旋转动画、缩放动画和平移动画。

例.
AlphaAnimation alphaAnimation=new AlphaAnimation(0.0f,1.0f);
alphaAnimation.setDuration(5000);
alphaAnimation.setRepeatMode(AlphaAnimation.REVERSE);
alphaAnimation.setRepeatCount( AlphaAnimation.INFINITE);
imageView.startAnimation(alphaAnimation);

补间动画start之后是以异步线程运行,不阻塞主线程。

2. 逐帧动画

逐帧(Frame)动画是按照提前准备好的静态图像顺序播放,利用人眼的“视觉暂留”原理,让用户产生动画错觉的动画效果。逐帧动画的工作原理比较简单,其实就是将一个完整的动画拆分成一张一张单独的图片,然后再将这些图片按照顺序依次播放。 

在使用逐帧动画时,首先需要在程序的res/drawable文件夹中创建好定义逐帧动画的XML文件,并在该文件的<item>标签中通过设置android:drawableandroid:duration分别指定需要显示的图片和每张图片显示的时间,在XML文件中<item>标签的顺序就是对应图片出现的顺序。根标签为 animation-list

例.res/drawable 中 frameAnimation.xml

<?xml version="1.0" encoding:"utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/img1" android:duration"3o"></item>
    <item android:drawable="@drawable/img2" android:duration"3o"></item>
    <item android:drawable="@drawable/img3" android:duration"3o"></item>
</animation-list>

为控件设置帧动画,要把逐帧动画作为图片设为背景

<Imageliew
    android:background="drawable/frameAnimation"  //要把逐帧动画作为图片设为背景
    android:id="@id+/imageView"
    ... ...
/> 

执行逐帧动画

ImageView imageView=findViewById(R.id.imageView);
AnimationDrawable animationDrawable= (AnimationDrawable) imageView.getBackground();
int i=0;
while (!animationDrawable.isRunning()){
    i++;
    animationDrawable.start();
    if(i==50){
        animationDrawable.stop();
        break;
    }
}

通过Java代码创建逐帧动画

AnimationDrawable animationDrawable=new AnimationDrawable();
animationDrawable.addFrame(getResources().getDrawable(R.drawable.img1),500);
animationDrawable.addFrame(...
    ... ...
ImageView imageView=findViewById(R.id.imageView);
imageView.setBackground(animationDrawable);

3. 属性动画

在Andrid3.0之后,Android给我们提供了一种全新的动画模式——属性动画(PropertyAnimation)它是一种对属性值不断进行操作的模式,也就是可以将值赋给指定对象的指定属性该指定对象可以是任意对象的任意属性。通过属性动画我们仍然可以对一个View进行平移、缩放、旋转和透明度渐变等操作,同时也可以对自定义View中的Point(点)对象进行动画操作。在实现这些动画操作时,我们只需要设置动画的运行时长、动画的类型、动画属性的初始值和结束值即可。
属性动画弥补了补间动画的一些缺陷,例如补间动画只能作用在View上,只能对View实现平移、缩放、旋转和透明度渐变动画,只能改变View的位置,不能对Viw自身进行修改。

(1) Animator类

Animator类提供了创建动画的基本结构,但是我们通常不会直接使用此类,因为它提供的功能较少,这些功能必须经过扩展才能为属性值添加动画效果。我们通常会使用Animator的子类来创建动画,常用的Animator子类如下:
ValueAnimator:属性动画的主计时引擎,它也可以计算要添加动画效果的属性值。它具有计算属性值所需要的核心功能,同时包含每个动画的计时详情、有关动画是否重复播放的信息、用于按收更新事件的监听器及设置评估自定义类型的功能。
ObjectAnimator:ValueAnimator的子类,用于设置目标对象和对象属性以添加动画效果。AnimatorSet:此类提供一种将所有动画组合在一起的机制,使这些动画可以一起运行.我们可以将动画设置为一起播放、按顺序播放或者在指定的延迟时间后播放。

① 使用ValueAnimator类添加动画效果

使用ValueAnimator类可以为动画播放期间某些类型的值添加动画效果,只需要指定一组要添加动画效果的Int类型、Float类型或颜色类型的值即可,我们可以调用 ValueAnimator类中的ofInt()方法ofFloat()方法ofObject()方法来获取要添加动画效果的值。

ValueAnimator valueAnimator=ValueAnimator.ofFloat(0f,100f);
valueAnimator.setDuration(1000);
valueAnimator.start();

上述代码调用ValueAnimator类的ofFloat()方法获取0f~100f之间的动画效果值;调用setDuration()方法设置动画播放时长为1000毫秒;调用start()方法开始播放动画。

② 使用ObjectAnimator类添加动画效果

ObjectAnimator类是ValueAnimator的子类,该类融合了ValueAnimator类的计时引擎和值计算,以及为目标对象的属性添加动画效果的功能。由于通过ObjectAnimator添加动画效果时,动画属性会自动更新,所以该类极大地简化了为任何对象添加动画效果的过程。可用静态方法ofInt()ofFloat()ofObject()实例化ObjectAnimator类,可以指定需要添加动画的对象该对象属性的名称,同时还可以指定在哪些值之间添加动画

例.
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"translationX",100f,50f,80f);
objectAnimator.setDuration(1000);
objectAnimator.start();

使用ObjectAnimator类添加动画效果时,需要添加动画效果的对象属性必须具有set<PopertyName>形式的Setter函数(采用驼峰式命名形式)。由于ObectAnimator类可以在动画播放过程中自动更新属性,所以它必须能够使用属性具备的setter函数访问指定的属性。例如,如果属性名称为name,则需要使用setName()方法访问name属性。

使用AnimatorSet类添加多个动画效果

通常情况下,我们会遇到根据一个动画的开始或结束时间来播放另一个动画。在Android中,我们可以将这些需要一起播放的动画存放在Animator类中,便于指定这些动画是同时播放按顺序播放还是在指定延迟时间后播放,同时我们还可以使用AnimatorSet类播放另一个AnimatorSet类的对象中的动画。

例.
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(objectAnimation1).with(objectAnimation2);//同时开始
animatorSet.play(objectAnimation0).before(objectAnimation1);//播放0在1之前
animatorSet.play(objectAnimation3).after(objectAnimation2);//播放3在2之后
        
AnimatorSet animatorSet2=new AnimatorSet();
ValueAnimator valueAnimator=ObjectAnimator.ofFloat(imageView,"translationX",100f);//上转型
animatorSet2.play(animatorSet).before(valueAnimator);//播放animatorSet在valueAnimator前
animatorSet2.start();
        
//顺序播放
animatorSet.playSequentially(Animator ... item 或 List<Animator> items);
//同时播放
animatorSet.playTogether();Animator ... item 或 Collection<Animator> items);

(2) 评估程序

评估程序(类接口)主要用于告知属性动画系统如何计算指定属性的值。评估程序使用Animatio类提供的计时数据(动画的起始值和结束值)来计算属性添加动画效果后的值。属性动画示化可提供的评估程序如下:

  • IntEvaluator:用于计算Int类型的属性值的默认评估程序。
  • FloatEvaluator:用于计算Float类型的属性值的默认评估程序。
  • ArgbEvaluator:用于计算颜色类型的属性值(用十六进制教表示)的默认评估程序。
  • TypeEvaluator:此接口用于自定义一个评估程序。如果要添加动画效果的对象属性值不是Int类型、Float类型或颜色类型,那么必须实现TypeEvaluator接口,才能指定如何计算对象的属性添加动画效果之后的值。如果不想使用默认的评估程序处理Int类型、Float类型或颜色类型的数据,还可以为这些类型的值指定自定义的TypeEvaluator。

(3) 插值器 Interpolator

插值器(类/接口)指定了如何根据时间计算动画中的特定值。例如,可以通过插值器指定动画以线性方式进行播放,也就是动画在整个播放期间匀速移动;也可以通过插值器指定动画使用非线性方式进行播放,比如动画可以在开始后加速并在结束前减速。在Android的android.view.animation包中包含的插值器如下:

  • AccelerateDecelerateInterpolator:该插值器的变化率在开始和结束时缓慢,但在中间会加快(默认)。
  • AccelerateInterpolator:该插值器的变化率在开始时较为缓慢,然后会加快。
  • AnticipateInterpolator:该插值器先反向变化,然后急速正向变化。
  • AnticipateOvershootInterpolator:该插值器先反向变化,然后急速正向变化,然后超过定位值最后返回最终值。
  • BounceInterpolator:该插值器的变化会跳过结尾处。
  • CycleInterpolator:该插值器的变化会在指定数量的周期内重复。
  • DecelerateInterpolator:该插值器的变化率开始很快、然后减速。
  • LinearInterpolator:该插值器的变化率恒定不变。
  • OvershootInterpolator:该插值器会急速正向变化,再超出最终值,然后返回。
  • TimeInterpolator:该接口用于自定义一个插值器。
例.
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"translationX",100f);
objectAnimator.setInterpolator(new LinearInterpolator());

(4) 动画监听器

动画监听器(一个接口)主要用于监听动画播放期间的重要事件。动画监听器包括Animator.AnimatorListenerAnimator.AnimatorUpdateListener

Animator.AnimatorListener

动画监听器Animator.AnimatorListener(接口)中有4个方法,分别是onAnimationStart()onAnimationEnd()onAnimationRepeat()onAnimationCancel()方法。

  • onAnimationStart():动画开始播放时调用。
  • onAnimationEnd():动画结束播放时调用。
  • onAnimationRepeat():动画重新播放时调用
  • onAnimationCancel():动画取消播放时调用,取消动画时也会调用onAnimationEnd()。

根据程序的功能需求,如果程序只需要实现Animator.AnimatorListener接口中的部分方法则可以扩展AnimatorListenerAdapter类,不用实现Animator.AnimatorListener接口,我们可以选择实现AnimatorListenerAdapter类中必要的一些方法。

例.
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(imageView,"alpha",1f,0f);
objectAnimator.addListener(new AnimatorListenerAdapter(){
    public void onAnimatonEnd(Animaton animaton){
            ((ObjectAnimator)animator).getTarget();//获取目标
    }
});

ValueAnimator.AnimatorUpdateListener

动画监听器ValueAnimator.AnimatorlpedateListener中只有1个方法onAnimationUpdate(),该方法在动画播放的每一帧都会被调用。如果使用接口ValueAnimator.AnimatorUpdateListenen监听某个动画播放的每一帧事件,多么可以调用ValueAnimator类的getAnimatorValue()方法获取动画添加效果之后生成的值。如果某个类中使用了ValueAnimator类,那么该类必须实现
ValueAnimator.AnimatorUpdateListener接口。

ValueAnimator valueAnimator=ValueAnimator.ofFloat(0f,100f);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) {
        float anumatedValue= (float) valueAnimator.getAnimatedValue();
        textView.setTranslationX(animtedValue);
    }
});

上述代码通过getAnimatedValue()方法获取某个控件添加动画效果之后的值;通过调用setTranslationX()方法将获取的动画值设置到对应的控件上。

4. 属性动画总结

ObjectAnimator objectAnimator1=ObjectAnimator.ofFloat(View,"translationX",100f);//X平移
ObjectAnimator objectAnimator2=ObjectAnimator.ofFloat(View,"translationY",100f);//Y平移
 
 
ObjectAnimator objectAnimator3=ObjectAnimator.ofFloat(View,"rotation",  0  ,  -90 );//中心点旋转
                                                        //起始值   结束值
ObjectAnimator objectAnimator4=ObjectAnimator.ofFloat(View,"rotationX",  0  , -90 , 90 );//围绕X轴旋转
                                                        //起始值 过程值 结束值
ObjectAnimator objectAnimator5=ObjectAnimator.ofFloat(View,"rotationY", 360 );//围绕Y轴旋转
                                                          //结束值
 
ObjectAnimator objectAnimator6=ObjectAnimator.ofFloat(View,"scaleX", 1.5f );//围X轴缩放 0->1.5
ValueAnimator objectAnimator7=ObjectAnimator.ofFloat(View,"scaleY", 1, 1.5f, 1);//围Y轴缩放 1->1.5->1
//向上转型
 
ObjectAnimator objectAnimator8=ObjectAnimator.ofFloat(View,"alpha", 0.0f );//透明度

控件中属性translationX , translationY , rotation , rotationX , rotationY , scaleX , scaleY , alpha 即使未在控件中写明,也会默认存在并有默认值。 

objectAnimator8.addListener(new AnimatorListenerAdapter() {
    public void onAnimationEnd(Animator animation) {
        ((ImageView)(((ObjectAnimator)animation).getTarget())).setAlpha(1.0f);
    }
});
objectAnimator8.setDuration(1000);
objectAnimator8.setRepeatCount(0);//为ValueAnimator.INFINITE表示无限循环
objectAnimator8.setRepeatMode(ValueAnimator.REVERSE);//重复方式可为REVERSE或RESTART
objectAnimator8.setInterpolator(new LinearInterpolator());//设置插值器
AnimatorSet animatorSet1=new AnimatorSet();
animatorSet1.play(objectAnimator1);                          //播放~
animatorSet1.play(objectAnimator1).with(objectAnimator2);    //播放~和~
animatorSet1.play(objectAnimator1).before(objectAnimator2);  //播放~在~之前
animatorSet1.play(objectAnimator1).after(objectAnimator2);   //播放~在~之后
 
//AnimatorSet可当Animator使用
AnimatorSet animatorSet2=new AnimatorSet();
animatorSet2.play(animatorSet1).before(objectAnimator2);
 
animatorSet2.start();                                       //启动AnimatorSet
 
boolean isrunning=animatorSet2.isRunning();                 //是否处于运行中
 
animatorSet2.pause();                                       //暂停

tag:Android动画;补间动画;逐帧动画;属性动画;ValueAnimator;ObjectAnimator;AnimatorSet;AnimationDrawable

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下嗷呜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值