本文是学习以下三位大神之后,整理的学习笔记,彩蛋在编号6
http://blog.csdn.net/lmj623565791/article/details/38067475
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html
http://www.tuicool.com/articles/baEfAzY
1. Property Animation
属性动画,这个是在Android 3.0中才引进的,以前学WPF时里面的动画机制好像就是这个,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。在Property Animation中,可以对动画应用以下属性:
- Duration:动画的持续时间
- TimeInterpolation:属性值的计算方式,如先快后慢
- TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
- Repeat Count and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
- Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
- Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影
2. Value Animator的工作方式
一、举个例子
1、某个对象的X坐标在40ms内从0移动到40 pixel.按默认的10ms刷新一次,这个对象会移动4次,每次移动40/4=10pixel。
2、改变插值方式后,该对象的运动形式也随之改变
上述例子的实现可以通关ValueAnimator来实现,现在有个印象即可
二、ValueAnimator工作流程图
此图是理解ValueAnimator的关键,现在不理解没关系,还是大致看一下,按顺序浏览,有个印象即可,不过浏览后续部分时需回来对照参考
ValueAnimator是Property Animation的执行类,ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。上图大致描述了ValueAnimator的工作流程,理解了就差不多对ValueAnimator了解了,当然后面会有具体介绍。
ValueAnimator的属性介绍:
TimeIntepolator:时间插值
TypeEvaluator:综合了时间插值、属性开始值、属性结束值计算出的属性当前值
duration:动画持续时间
startPropertyValue:属性开始值
endPropertyValue:属性结束值
start():动画启动方法
四、ValueAnimator实现步骤
一、计算当前的属性值,ex.t = 5 ms时,x的值:
1、ValueAnimator根据动画已进行的时间跟动画总时间(duration)的比计算出一个时间因子(0~1),如上例中10ms时,计算时间因子t:即经过的时间百分比:t=10ms/40ms=0.25
2、然后根据TimeInterpolator计算出插值因子,上述例子中用了AccelerateDecelerateInterpolator,计算公式为(input即为时间因子):(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; 经插值计算(inteplator)后的插值因子:大约为0.15
3、最后TypeEvaluator通过这个因子计算出属性值,计算方法为 :
1
2
3
4
|
public
Float evaluate(
float
fraction, Number startValue, Number endValue) {
float
startFloat = startValue.floatValue();
return
startFloat + fraction * (endValue.floatValue() - startFloat);
}
|
参数分别为上一步的插值因子,开始值与结束值。最后根据TypeEvaluator计算出在10ms时的属性值:0.15*(40-0)=6pixel。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
ValueAnimator valueAnimator =
new
ValueAnimator();
valueAnimator.setDuration(
3000
); //设置动画时间
valueAnimator.setObjectValues(
new
PointF(
0
,
0
)); //设置目标值
valueAnimator.setInterpolator(
new
LinearInterpolator()); //设置插值方式
valueAnimator.setEvaluator(
new
TypeEvaluator<PointF>() //设置当前值得计算方式
{
// fraction = t / duration
@Override
public
PointF evaluate(
float
fraction, PointF startValue, //设置当前属性值得计算方式
PointF endValue)
{
Log.e(TAG, fraction *
3
+
""
);
// x方向200px/s ,则y方向0.5 * 10 * t
PointF point =
new
PointF();
point.x =
200
* fraction *
3
;
point.y =
0
.5f *
200
* (fraction *
3
) * (fraction *
3
);
return
point;
}
});
valueAnimator.addUpdateListener(
new
AnimatorUpdateListener() //设置监听器,并在监听器中给对象赋当前属性值
{
@Override
public
void
onAnimationUpdate(ValueAnimator animation)
{
PointF point = (PointF) animation.getAnimatedValue();
mBlueBall.setX(point.x);
mBlueBall.setY(point.y);
}
});
|
3. Object Animator的工作方式
如果理解了Value Animator后,Object Animator理解起来也不是太难。因为他们很相似,Value Animator分两步执行,而Object Animator合二为一了,主要是省去了第二步,因为Object Animator已经在初始化时就指定了要改变的属性值了,不多说,上代码:
1
2
3
4
|
ObjectAnimator
.ofFloat(view,
"rotationX"
,
0
.0F,
360
.0F)
.setDuration(
500
)
.start();
|
对于Object Animator,有如下注意点:
1、提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素属性。
2、动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用Object Animator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。
1
2
3
4
5
6
7
8
9
|
anim.addUpdateListener(
new
AnimatorUpdateListener()
{
@Override
public
void
onAnimationUpdate(ValueAnimator animation)
{
view.postInvalidate();
view.invalidate();
}
});
|
4. 动画事件的监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall,
"alpha"
,
0
.5f);
anim.addListener(
new
AnimatorListener()
{
@Override
public
void
onAnimationStart(Animator animation)
{
Log.e(TAG,
"onAnimationStart"
);
}
@Override
public
void
onAnimationRepeat(Animator animation)
{
// TODO Auto-generated method stub
Log.e(TAG,
"onAnimationRepeat"
);
}
@Override
public
void
onAnimationEnd(Animator animation)
{
Log.e(TAG,
"onAnimationEnd"
);
ViewGroup parent = (ViewGroup) mBlueBall.getParent();
if
(parent !=
null
)
parent.removeView(mBlueBall);
}
@Override
public
void
onAnimationCancel(Animator animation)
{
// TODO Auto-generated method stub
Log.e(TAG,
"onAnimationCancel"
);
}
});
anim.addListener(
new
AnimatorListenerAdapter()
{
@Override
public
void
onAnimationEnd(Animator animation)
{
Log.e(TAG,
"onAnimationEnd"
);
ViewGroup parent = (ViewGroup) mBlueBall.getParent();
if
(parent !=
null
)
parent.removeView(mBlueBall);
}
});
anim.start();
|
5. 动画的组合Animator Set
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall,
"scaleX"
,
1
.0f, 2f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall,
"scaleY"
,
1
.0f, 2f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall,
"x"
, cx , 0f);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall,
"x"
, cx);
/**
* anim1,anim2,anim3同时执行
* anim4接着执行
*/
AnimatorSet animSet =
new
AnimatorSet();
animSet.play(anim1).with(anim2);
animSet.play(anim2).with(anim3);
animSet.play(anim4).after(anim3);
animSet.setDuration(
1000
);
animSet.start();
|
6. ViewPropertyAnimator
不知道为了什么,网上的教程,把这个东西放到了最后,但是这个可是超级好用的啊,搞不懂- 这个类操作View对象的。
- 提供链式调用设置多个属性动画,这些动画同时进行的。
- 更好的性能,多个属性动画是一次同时变化,只执行一次UI刷新。
- 每个属性提供两种类型方法设置。
- 这个类只能通过View的animate()获取引用进行通话设置。
imageView.animate()
.setDuration(4000)
.rotationY(45f)
.translationX(imageView.getWidth())
.alpha(0f);