您的位置:首页 > 移动开发 > Android开发

Android属性动画和帧动画

2017-03-07 08:01 323 查看
 Android动画有4种:变换动画,属性动画,帧动画,布局动画。
Tween Animation 变换动画
Frame Animation 帧动画
Layout Animation 布局动画
Property Animation 属性动画
一.逐帧动画
1.逐帧动画原理:
把动画过程的每张静态图片都收集起来,然后在将他们组合起来连贯进行播放,利用人眼“视觉暂留”原理,给用户造成“动画”的错觉。类似于早期电影工作原理。
2.逐帧动画使用:
2.1在XML中定义使用:
XML的文件位置放在/res下的drawable目录中。根标签是<animation-list/>,在<animation-list/>中使用<item.../>子元素定义动画全部帧,并指定个帧持续时间。
例子frame.xml:
<?xml version="1.0"
encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/img0"
android:duration="60"></item>
<item
android:drawable="@drawable/img1"
android:duration="60"></item>
...
</animation-list>
定义了一个ImageView作为动画的载体,将之前定义的xml文件作为ImageView的背景:
imageView.setBackgroundResource(R.drawable.frame);
定义AnimationDrawable对象,该对象从ImageView的背景获取:
AnimationDrawable drawable=(AnimationDrawable)imageView.getBackground();
drawable.start();
2.2在Java代码中使用:
创建AnimationDrawable对象,调用addFrame(Drawable frame, int durtion)向该动画中添加帧。每次调用一次addFrame方法,相当于一个<item/>。
例子:
anim =
new
AnimationDrawable();
int
id = getResources().getIdentifier("frame0"
, "drawable",getPackageName());
Drawable drawable = getResources().getDrawable(id);
anim.addFrame(drawable,
300);
//这只添加了一帧
将动画设置为ImageView的背景:
imageView.setBackgroundDrawable(anim);
anim.start();
2.3注意:
AnimationDrawable代表的动画默认是不播放的,必须在程序中启动动画。AnimationDrawable提供start()和stop()方法启动和停止动画。
XML中的android:onshot控制动画是否循环播放,在Java代码中为anim.setOneShot(false);
二.属性动画
1.属性动画工作方式:
参考:http://blog.csdn.net/niu_gao/article/details/50925997
https://developer.android.google.cn/guide/topics/graphics/prop-animation.html
假设一个对象有一个属性x,通过属性动画动态更改该值,假设在40ms内将x的值从0渐变到40,如下图所示:

这是一个使用线性插值的对象,表示对象匀速移动。
可以变速地改变x的值,可以一开始加速增加x的值,后面减速增加x的值,如下图所示:

在前20ms,x值加速增大,在后20ms,x值增大的速度降低。
每种改变x值速度的方式都叫做时间插值器TimeInterpolator,第一张图中使用的时间插值器叫做LinearInterpolator,第二张图中使用的时间插值器叫做AccelerateDecelerateInterpolator。动画开始后,时间插值器会根据对应的算法计算出某一时刻x的值,然后我们就可以用该计算出的值更新对象中x属性的值,这就是属性动画的基本工作原理。
画相关的关键对象:

要开始一个动画,需创建一个ValueAnimator 然后告诉它所要动画的属性的开始和结束的值,还有动画持续的时间。当你调用start() 时,动画就开始了。在动画进行期间,ValueAnimator 跟据动画的持续时间和已经过的时间,计算出一个表示进度的比例的分数(0和1之间),进度分数代表了动画已进行的时间的百分比,0代表0%,1代表100%。
 当ValueAnimator 计算完成一个进度分数,它就调用TimeInterpolator 去计算一个插值分数。插入分数结合所设置的时间插值把进度分数映射到一个新的分数。例如,在图2中,因为动画缓慢加速,在 t = 10 ms时,插值分数为.15。
 当计算插值函数时,ValueAnimator 会调用适当的TypeEvaluator来基于插值函数、开始值、结束值计算你在动画的属性的值。例如,在图2中,插值函数值在 t = 10 ms时为.15 ,所以些时属性的值将是.15 X (40 - 0)。

Evaluator告诉属性动画系统如何计算某个属性的值。它们跟据Animator 类提供的时间信息,动画的开始值和结束值计算动画的值。属性动画系统提供了以下evaluator:

Class/InterfaceDescription
IntEvaluator计算int 型属性的默认evaluator。
FloatEvaluator计算float型属性的默认 evaluator。
ArgbEvaluator计算用十六进制值表示的颜色属性的默认evaluator 。
TypeEvaluator一个允许你创建自己的evaluator的接口。如果你要动画的对象的属性非int, float、或color,你就必须实现TypeEvaluator 接口来定义如何计算对象属性的动画值。如果你想改变处理int, float, 和 color属性的默认行为,你也可以为它们指定自定义的TypeEvaluator 。
 时间插值器定义了时间函数如何计算动画的值。

类/接口描述
AccelerateDecelerateInterpolator中间快两头慢的插值器。
AccelerateInterpolator一直加速的插值器。
AnticipateInterpolator先向后再猛向前的插值器。
AnticipateOvershootInterpolator先向后,再猛向前,超过结束值后再回到结束值的插值器。
BounceInterpolator最后跳一下的插值器。
CycleInterpolator重复循环播放的插值器。
DecelerateInterpolator一直减速的插值器。
LinearInterpolator定速播放的插值器。
OvershootInterpolator先猛向前直到超过结束值然后再回到开始值的插值器。
TimeInterpolator让你能实现自己的插值器的接口。
2.ValueAnimator:
属性动画的主要时间引擎,负责计算各个帧的属性值。它定义了属性动画的绝大部分核心功能,包括计算各帧的相关属性值,负责处理更新事件,按属性值的类型控制计算规则。属性动画主要由两方面组成:(1)计算各帧的相关属性值,(2)为对象设置计算后各属性值。ValueAnimator负责(1),因此必须根据ValueAnimator计算并监听更新值更新属性值。
2.1使用ValueAniamtion创建动画:
(1)调用ValueAnimator的ofInt()、ofFloat()或ofObject()静态方法创建实例。
(2)调用ValueAnimator的setXxx()方法持续时间等属性值。
(3)创建自定义的Interpolator,调用setInterpolator(TimeInterpolator value)为ValueAniamtor设置自定义的Interpolator;(可选,不设置默认为缺省值)
(4)创建自定义的TypeEvaluator,调用setEvaluator(TypeEvaluator value)为ValueAnimator设置自定义的TypeEvaluator;(可选,不设置默认为缺省值)
(5)为ValueAnimator注册AnimatorUpdateListener监听器,监听ValueAnimator更新属性值,并将值赋值到对象上。
(6)调用Animator的star()方法启动动画。

3.ObjectAnimator: 继承ValueAnimator,不需要注册AnimatorUpdateListener监听器。
使用ObjectAnimator注意点:
(1)要为该对象属性提供setter方法。
(2)若调用ObjectAnimator的ofInt()、ofFloat()或ofObject()时value...参数只提供一个值,该值为结束值。那么该对象要为该属性提供一个getter方法,其返回值为开始值。
(3)若对象是View,为了显示动画效果,可能还要在onAnimationUpdate()事件监听方法中调用View.invalidate()刷新屏幕。

使用步骤:
(1)创建ValueAniamtor或ObjectAnimator创建对象,可以从XML资源文件加载动画或调用ValueAnimator、ObjectAniamtor静态工厂方法创建对象。
(2)根据需要为Aniamtor对象设置属性。
(3)若需要监听Animator动画开始事件、结束事件、重复事件、动画值改变事件,并根据事件提供响应处理代码,要为Aniamtor对象设置监听器。
(4)若有多个动画需要按次序或同时播放,用AnimatorSet组合实现。
(5)调用Animator对象的start()启动动画。

3.AniamtorSet:
Animator子类,用于组合多个Animator,并指定Animator播放次序。
例子:
AnimatorSet
bouncer =
new
AnimatorSet();
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);
ValueAnimator fadeAnim
=
ObjectAnimator.ofFloat(newBall,
"alpha",
1f,
0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet
=
new
AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

4.Keyframe:
keyFrame是一个 时间/值 对,通过它可以定义一个在特定时间的特定状态,而且在两个keyFrame之间可以定义不同的Interpolator,就相当多个动画的拼接,第一个动 画的结束点是第二个动画的开始点。KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的 KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象。
例子:
Keyframe keyframeAlpha=Keyframe.ofFloat(0f,0.5f);
Keyframe keyframeAlpha1=Keyframe.ofFloat(0.5f,0.2f);
Keyframe keyframeAlpha2=Keyframe.ofFloat(1f,1.0f);
PropertyValuesHolder propertyValuesHolder=PropertyValuesHolder.ofKeyframe("alpha",keyframeAlpha,keyframeAlpha1,keyframeAlpha2);
ObjectAnimator objectAnimator=ObjectAnimator.ofPropertyValuesHolder(objectAnimationText,propertyValuesHolder,propertyValuesHolder1);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息