Android 动画框架

Android提供了三种动画系统:

  1. Property Animation: 属性动画,3.0引入,比较灵活,能够作用于所有对象
  2. View Animation:视图动画,只能作用于view对象,使用比较简单。
  3. Drawable Animation:帧动画,通过连续的加载 Drawable资源来实现动画效果。

属性动画(Property Animation)

概述

属性动画是一个健壮的框架,能够让你将几乎任何东西做成动画。属性动画能够在给定的时间内,按照给定的策略随时间改变对象的属性值,不论该对象是否能够在屏幕上显示。

使用属性动画只需要做三件事:

  1. 指定动画作用于对象的哪个属性;
  2. 指定动画的时长;
  3. 指定属性的举值区间。

属性动画定义了动画的五个特点: 1. 时长(Duration):即动画持续的时间; 2. 时间插值(Time interpolation):如何根据过去的时间计算属性值,即定义了属性值对时间的函数关系 3. 重复的次数和行为(Repeat count and behavior):重复多少次,能够回放等 4. 动画组(Animator sets):多个动画效果的组合,是同时进行还是顺序执行还是延时执行等 5. 帧刷新频率(Frame refresh delay):默认的帧刷新频率是10ms,你也可以指定,但是这取决于系统的繁忙程度和系统的性能。

属性动画的工作原理

上图是属性动画框架的主要类的关系图。

ValueAnimator记录动画的持续时间、当前的属性值,取值区间等;封装了一个 TimeInterpolator(时间插值器,定义了时间插值因子)、一个 TypeEvaluator(类型估值器,定义了如何根据插值因子计算属性值)。具体工作流程如下:

  1. 动画开始后,ValueAnimator先根据逝去的时间计算 elapsed fraction (逝去时间的比例因子),该值随着时间的过去,在0-1之间取值,0表示刚开始,1表示结束
  2. 计算好elapsed fraction 之后,ValueAnimator调用TimeInterpolator,计算 interpolated fraction(插值因子)
  3. 计算好 interpolated fraction之后,ValueAnimator调用TypeEvaluator,根据插值因子、初始值和结束值,计算当前的属性值。

属性动画和视图动画的区别

视图动画只能作用于view对象,同时只能作用于view对象的一部分属性,只能修改view drawn的位置,不能改变View的实际位置。

相比之下,属性动画更加健壮,它能够动态修改所有对象的任何属性。但是视图动画使用比较简单。所以如果视图动画能够满足需求,可以考虑使用view动画

API 概述

属性动画相关的类大部分定义在 android.animation包下,主要定义了Animator和Evaluator,由于视图动画已经在android.view.animation包下定义了插值器,所以属性动画也使用同样的插值器,当这些插值器不能够满足需求的时候,可以自定义自己的插值器。

使用ValueAnimator

实例化ValueAnimator通常通过工厂方法: ofInt(), ofFloat()或者 ofObject()等,例如:

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

如果要使用动画产生的插值,可以通过设置 AnimatorUpdateListener,例如:

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator updatedAnimation) {        // You can use the animated value in a property that uses the        // same type as the animation. In this case, you can use the        // float value in the translationX property.        float animatedValue = (float)updatedAnimation.getAnimatedValue();        textView.setTranslationX(animatedValue);    }});

拿到产生的插值根据需要使用。

使用ObjectAnimator

ObjectAnimator 是ValueAnimator的子类,它能够直接作用于对象的某个属性,而不必像ValueAnimator一样增加AnimatorUpdateListener监听,对象的属性能够自动更新。

实例化一个ObjectAnimator需要指定对象的属性名称,和取值区间

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);animation.setDuration(1000);animation.start();

为了ObjectAnimator能够正确工作,必须保证:

  1. 动画作用的属性必须有对应的set方法,如果没有,有三种方法: a. 增加set方法; b.使用包装类; c. 使用ObjectAnimator。
  2. 如果只为取值区间指定一个值,那么这个值会被当做区间的end value,这个时候,会通过属性的get方法获得当前值作为初始值,因此此时需要该属性有对应的get方法;
  3. get和set方法必须作用于相同类型;
  4. 有时需要使用 invalidate() 方法,才能在屏幕上看到动画效果,这取决于视图的属性

使用AnimatorSet

使用AnimatorSet允许将多种动画进行组合,实现动画的同时、顺序、延时播放发等效果。

动画监听

属性动画框架提供了两种监听,用来接收与动画相关的监听,分别是:

  1. Animator.AnimatorListener
  2. ValueAnimator.AnimatorUpdateListener(当使用ValueAnimator时,实现该监听是必须的)

使用TypeEvaluator

估值器的作用是根据 插值因子、初始值和结束值,计算出新的属性值。 属性动画默认支持int, float或 color类型的属性,分别对应 IntEvaluator, FloatEvaluator和 ArgbEvaluator,当动画的作用的属性值类型不是Android支持的类型时,需要自己实现估值器,只需要继承TypeEvaluator ,并实现evaluate(float fraction, Object startValue, Object endValue) 方法。

使用插值器

插值器的作用是,根据elapsed fraction,计算插值因子,它定义了插值因子和elapsed fraction之间的函数关系。不同的插值器定义了不同的插值因子的计算方法,从而产生不同的动画效果。Android预定义了多种插值器,能够满足日常的开发需求,如果开发需求无法满足,可以自定义实现插值器。实现 TimeInterpolator接口即可。

指定关键帧

一个关键帧是一个时间/值对,用来指定动画在某一时刻的状态,每个关键帧同样可以拥有插值器,用来控制上一帧与该帧之间的行为。其用法如下:

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

使用 ofInt(), ofFloat()或 ofObject()等方法实例化关键帧,然后,使用关键帧定义一个PropertyValuesHolder,最后实例化一个ObjectAnimator就可以了。

对view使用属性动画

view动画只能改变view在屏幕上绘制的位置,并不能改变view的实际位置,因为view的属性其实是没有改变的,使用属性动画真好可以克服这个弊端。为了对view使用属性动画,从3.0开始,Android为view添加了一些新的属性,包括:

  1. translationX 和 translationY:
  2. rotation, rotationX, 和 rotationY
  3. scaleX 和 scaleY
  4. pivotX 和 pivotY:
  5. x 和 y:
  6. alpha

ViewPropertyAnimator提供了一种并行执行多个属性动画的方法,同时代码十分简洁和可读。

在xml中声明属性动画

属性动画框架支持用XML定义属性动画,用来将动画定义和代码分离,实现重用。为了和view动画区分,从3.1开始,用xml定义的属性动画放在 res/animator/ 目录下。

使用xml方式定义属性动画分为以下几步:

  1. 使用xml定义属性动画
  2. 在代码中加载动画,
  3. 为动画设置target
  4. 开启动画。

对UI性能的影响

动画需要额外的渲染工作,与动画相关的工作会被加到 rendering pipeline的动画阶段,使用Profile GPU Rendering工具能够让你定位问题。

视图动画(View Animation)

View Animation系统是用来对view执行补间动画的,它主要是对view的内容进行大小、位置、旋转和透明度的一系列变换实现的。

使用视图动画有两种方式,代码实现或者使用xml定义,推荐使用xml方式,这种方式将动画的定义和代码分离,避免硬编码,提供复用性。

示例:

                            

首先定义一个xml,放置在res/anim/目录里,

然后在代码中这样使用:

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);spaceshipImage.startAnimation(hyperspaceJumpAnimation);

先加载动画,然后播放动画。

也可以给动画设置一个播放的时间,然后在设置给view。

注意:不管动画怎么变,view的边界都不会变动,即使动画超过了view的边界,也不会变形或者裁剪,除非超过了父View的边界。

帧动画(Drawable Animation)

帧动画是通过连续的加载drawable资源的方式实现动画效果的,就好像放电影。AnimationDrawable 是帧动画的基础。

帧动画有两种定义方式,一种是在代码中使用AnimationDrawable,另一种是使用xml定义,后者比较简单。

下面是帧动画的常用使用方式:

`            ` 

首先定义一个xml文件,保存在res/drawable/ 目录下,然后在代码里:

AnimationDrawable rocketAnimation;    public void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.main);      ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);      rocketImage.setBackgroundResource(R.drawable.rocket_thrust);      rocketAnimation = (AnimationDrawable) rocketImage.getBackground();    }    public boolean onTouchEvent(MotionEvent event) {      if (event.getAction() == MotionEvent.ACTION_DOWN) {        rocketAnimation.start();        return true;      }      return super.onTouchEvent(event);}

先将帧动画设置为imageview的背景,然后获得AnimationDrawable,最后开启动画。

注意:不要在activity的oncreate()回调里调用start方法,因为此时动画还没有完全attached 到window上,如果需要在不需要用户交互的时候立马执行动画,可以考虑在 activity的onWindowFocusChanged()里调用start()

更多相关文章

  1. android通过自定义schame和host来启动app
  2. Android(安卓)WebView加载页面的输入框被软键盘遮挡的问题
  3. android 绕过R文件,通过代码获取styleable的属性
  4. Android(安卓)Activity界面跳转动画讲解
  5. 【Android】AndroidManifest 中original-package标签
  6. Android(安卓)Property动画——ObjectAnimator使用
  7. Android之RecyclerView简单使用(三)
  8. android WebView(二)缩放
  9. 浅谈Android中常用的五种布局方式

随机推荐

  1. android资源管理和使用资源 (2015.12.1)
  2. Android(安卓)SDK Installed On Mac
  3. Android调用平台功能具体技巧分享
  4. android的多媒体数据库
  5. 性能优化之Java(Android)代码优化
  6. android 启动过程及init.rc
  7. iOS Airplay--Airtunes音乐播放在Android
  8. 【Android】Error[*,*]Could not find met
  9. 详解android:scaleType属性
  10. android sdk配置