补间动画只能定义起始和结束两个帧在“透明度”、“旋转”、“倾斜”、“位移”4个方面的变化,逐帧动画也只能是播放多个图片,无法满足我们日常复杂的动画需求,所以谷歌在3.0开始,推出了属性动画(property animation)
属性动画已经不再是针对View来设计的了,也不仅限定于只能实现移动、缩放、淡入淡出这几种动画操作,同时也不再是一种视觉上的动画效果了。它实际上是一种不断的对值进行操作的机制,并将值赋值到指定对象的指定属性上,可以是任意对象的任意属性。
ValueAnimator是整个属性动画机制中最核心的一个类,负责计算动画的起始值和结束值之间的动画过度,我们只需要把起始值和结束值以及运行时间提供给ValueAnimator,ValueAnimator会自动计算出从起始值到结束值之间的过度值。另外ValueAnimator还负责管理动画的播放此时,播放模式,以及设置监听器等
例如我们需要在2秒内将值从0过度到5再过度到0的动画,我们就可以这样写:
public class MainActivity extends Activity implements OnClickListener {
private ImageView iv;
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
iv = (ImageView) findViewById(R.id.image);
bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt:
ValueAnimator va = ValueAnimator.ofFloat(0f, 5f, 0f);
va.setDuration(1000);
va.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float i = (float) animation.getAnimatedValue();
Log.d("TTTT", "运行时间:" + i);
}
});
va.start();
break;
}
}
}
在上面的代码中通过addUpdateListener()方法添加了一个动画监听器,在动画执行的过程中会不断的回调onAnimationUpdate方法,在这个方法中将当前的值打印出来,会发现系统自动计算了中间过度过程的值
ValueAnimator是对过度值进行了一个计算,ObjectAnimator则可以直接对任意对象属性进行动画操作
譬如我们想要将一个图片3秒内从透明变成常规再变成透明
public class MainActivity extends Activity implements OnClickListener {
private ImageView iv;
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
iv = (ImageView) findViewById(R.id.image);
bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt:
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", 0f, 1f, 0f);
oa.setDuration(3000);
oa.start();
break;
}
}
}
target:传入我们要操作的对象
propertyName:传入要操作的对象属性
values:想要实现的动画值(长度不固定)
rotation——旋转
translationX——X轴方向位移
translationY——Y轴方向位移
scaleX——X轴方向缩放
scaleY——Y轴方向缩放
通过名字就可以看出这个类是用来实现动画集合的,这个类可以帮助我们将多个动画组合起来一起播放。
AnimatorSet提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
after(Animator anim) 将现有动画插入到传入的动画之后执行
after(long delay) 将现有动画延迟指定毫秒后执行
before(Animator anim) 将现有动画插入到传入的动画之前执行
with(Animator anim) 将现有动画和传入的动画同时执行
譬如我们要实现图片在移动的同时旋转
public class MainActivity extends Activity implements OnClickListener {
private ImageView iv;
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
iv = (ImageView) findViewById(R.id.image);
bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt:
ObjectAnimator traslationAnimator = ObjectAnimator.ofFloat(iv, "translationX", -600f, 0f);
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(iv, "rotation", 0f, 360f);
AnimatorSet as = new AnimatorSet();
as.play(rotationAnimator).with(traslationAnimator);
as.setDuration(3000);
as.start();
break;
}
}
}
在很多时候,我们希望可以监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理。这个功能是完全可以实现的,Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。
大家已经知道,ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法的。另外AnimatorSet也是继承自Animator的,因此addListener()这个方法算是个通用的方法。
添加一个监听器的代码如下所示:
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
可以看到,我们需要实现接口中的四个方法,onAnimationStart()方法会在动画开始的时候调用,onAnimationRepeat()方法会在动画重复执行的时候调用,onAnimationEnd()方法会在动画结束的时候调用,onAnimationCancel()方法会在动画被取消的时候调用。
但是也许很多时候我们并不想要监听那么多个事件,可能我只想要监听动画结束这一个事件,那么每次都要将四个接口全部实现一遍就显得非常繁琐。没关系,为此Android提供了一个适配器类,叫作AnimatorListenerAdapter,使用这个类就可以解决掉实现接口繁琐的问题了,如下所示:
anim.addListener(new AnimatorListenerAdapter() {
});
这里我们向addListener()方法中传入这个适配器对象,由于AnimatorListenerAdapter中已经将每个接口都实现好了,所以这里不用实现任何一个方法也不会报错。那么如果我想监听动画结束这个事件,就只需要单独重写这一个方法就可以了,如下所示:
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
转自郭霖博客:http://blog.csdn.net/guolin_blog/article/details/43536355