Android动画有4种:变换动画,属性动画,帧动画,布局动画。
Tween Animation 变换动画
Frame Animation 帧动画
Layout Animation 布局动画
Property Animation 属性动画
一.逐帧动画
1.逐帧动画原理:
把动画过程的每张静态图片都收集起来,
然后在将他们组合起来连贯进行播放,利用人眼“视觉暂留”原理,给用户造成“动画”的错觉。类似于早期电影工作原理。
2.逐帧动画使用:
2.1在XML中定义使用:
XML的文件位置放在
/res下的drawable目录中。根标签是,在中使用子元素定义动画全部帧,并指定个帧持续时间。
例子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方法,相当于一个 。
例子:
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/Interface |
Description |
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);