属性动画
整理自:
http://blog.csdn.net/guolin_blog/article/details/43536355
三类动画:
补间动画
属性动画
帧动画(一张一张图片轮播,有可能会OOM,而且很简单,这里不讲了)
1、属性动画(property animation)
为啥用属性动画不用补间动画:
- 你希望View有一个颜色的切换动画
- 你希望可以使用3D旋转动画
- 你希望当动画停止时,View的位置就是当前的位置
- 对一个非View的对象进行动画操作:比如说我们有一个自定义的View,在这个View当中有一个Point对象用于管理坐标,然后在onDraw()方法当中就是根据这个Point对象的坐标值来进行绘制的。也就是说,如果我们可以对Point对象进行动画操作,那么整个自定义View的动画效果就有了。
1-1、ValueAnimator
设置数值上的平滑增加会减小
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
用addUpdateListener()方法来添加一个动画的监听器
运行结果:
Paste_Image.png
将一个值在5秒内从0过渡到5,再过渡到3,再过渡到10的代码:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);
anim.setDuration(5000);
anim.start();
其他简单的设置:
- 调用setStartDelay()方法来设置动画延迟播放的时间
- 调用setRepeatCount()和setRepeatMode()方法来设置动画循环播放的次数以及循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思。
1-2、ObjectAnimator
1-2-1、动画举例
ObjectAnimator可以直接对任意对象的任意属性进行动画操作,比如说View的alpha属性。
因为ObjectAnimator其实是继承自ValueAnimator的,说明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它们的用法也非常类似。
- 透明度
Eg:将一个TextView在5秒中内从常规变换成全透明,再从全透明变换成常规
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
- 旋转
将TextView进行一次360度的旋转
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
- 移动
将TextView先向左移出屏幕,然后再移动回来
float curTranslationX = textview.getTranslationX(); //getTranslationX()方法来获取到当前TextView的translationX的位置
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);
animator.setDuration(5000);
animator.start();
- 缩放
将TextView在垂直方向上放大3倍再还原
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
animator.setDuration(5000);
animator.start();
这里注意如果要对一个View进行缩放,这样做是没用的(好像不能直接对"scale"进行操作),要分别对"scaleY"和"scaleX"进行操作:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scale", 1f, 3f, 1f);
效果:
缩放
ofFloat()
的第二个参数除了上述这些还有哪些呢?
其实ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法,因此alpha属性所对应的get和set方法应该就是:
public void setAlpha(float value);
public float getAlpha();
textview对象的确有这两个方法,并且这两个方法是由View对象提供的,也就是说不仅TextView可以使用这个属性来进行淡入淡出动画操作,任何继承自View的对象都可以的。
1-2-2、组合动画
注意这个组合动画的做法也适用于ValueAnimator!
借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
- after(Animator anim) 将现有动画插入到传入的动画之后执行
- after(long delay) 将现有动画延迟指定毫秒后执行
- before(Animator anim) 将现有动画插入到传入的动画之前执行
- with(Animator anim) 将现有动画和传入的动画同时执行
Eg:让TextView先从屏幕外移动进屏幕,然后开始旋转360度,旋转的同时进行淡入淡出操作
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
1-2-3、动画监听
注意这个动画监听的做法也适用于ValueAnimator!
我们希望可以监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理。
Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。
示例代码:
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) {
//在动画被取消的时候调用
}
});
也可以使用适配器类AnimatorListenerAdapter
来实现这四个方法中的任意一个方法,免得每次都要将四个接口全部实现一遍(假设只想要在动画结束之后设定一些逻辑):
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
因为
1-2-4、使用XML编写动画
通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松,比如某个将通用的动画编写到XML里面,我们就可以在各个界面当中轻松去重用它。
如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:
- <animator> 对应代码中的ValueAnimator
- <objectAnimator> 对应代码中的ObjectAnimator
- <set> 对应代码中的AnimatorSet
- 从0到100平滑过渡的动画:
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:valueType="intType"/>
- 将一个视图的alpha属性从1变成0
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"/>
- 复杂的组合动画操作,比如将一个视图先从屏幕外移动进屏幕,然后开始旋转360度,旋转的同时进行淡入淡出操作
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially" >
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<set android:ordering="together" >
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
<set android:ordering="sequentially" >
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" >
</objectAnimator>
</set>
</set>
</set>
在代码中将xml动画加载进来:
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view); //setTarget()方法将这个动画设置到某一个对象上面
animator.start();
2、补间动画
概述:对View进行移动、缩放、旋转和淡入淡出,并且我们还可以借助AnimationSet来将这些动画效果组合起来使用,除此之外还可以通过配置Interpolator来控制动画的播放速度