安卓动画入门教程 Animation in Android
概述
安卓有强大的动画,不管是view的动画,还是Activity切换的动画。安卓有三种动画系统,但最重要的就是属性动画(property animations)。属性动画允许我们去给任何的对象的属性增加动画。
这个属性动画可以应用到安卓应用的任何东西。一个典型的用法就是给view动态的运动,比如说位置的高棉,旋转,扩展大小或者颜色变化。
安卓中的动画和一些资源很像,都可以定义在xml文件或者java代码
动画的类型
事实上在安卓有两大不同的动画框架:
- Property Animations (属性动画):在Android 3.0引入的最强大和灵活的动画系统。
- View Animations :稍微慢一点和不是那么订货,自从Property Animations 引入后被废弃了
在这量大动画框架之下,又有5中相关的动画类型:
- Property Animations 一个有两个值的动画,经常在对view使用动画的时候引入,比如说旋转一个图片或者淡出一个button。
- Activity Transitions 这是一个过度的动画,比如说Activity进入屏幕
- Fragment Transitions fragment进入或者退出屏幕产生的动画
- Layout Animation 允许我们给任何的layout container或者viewgroup增加动画,比如说ListView、只要layout加上了动画,layout里面的元素也会被加上元素
- Drawable Animations 可以显示drawable的时候显示动画
Property Animations
Property Animations是安卓3.0的引入的新特性。
给view动画的主要属性有
alpha:渐入或渐出
rotation, rotationX, rotationY;旋转或者反转
scaleX, scaleY:放大或者缩小
x,y,z:位置
translationX, translationY, translationZ (API 21+):位置改变
过去,在适配3.0之前的设备要使用NineOldAndroids 。但是NineOldAndroids 现在被废弃了再也不支持了,但你还是可以在build.gradle加上依赖
compile 'com.nineoldandroids:library:2.4.0'
AndroidViewAnimations 这个库可以支持老设备,有需求的朋友可以看看。
干货来啦!!!
使用ObjectAnimator
我们可以使用 ObjectAnimator方法去给一个指定的对象加上何时的属性,然后执行简单的动画
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(tvLabel, "alpha", 0.2f);
fadeAnim.start();
上面的代码是button渐出。注意到alpha是一个字符串类型,ObjectAnimator 是依赖于反射,使用button的getAlpha和set Alpha来显示动画
我们也可以使用property system去执行动画,
ObjectAnimator fadeAltAnim = ObjectAnimator.ofFloat(image, View.ALPHA, 0, 1);
fadeAltAnim.start();
这个应该是更快一点,因为运行中的反射会慢一点,属性支持 ALPHA, ROTATION, ROTATION_X, ROTATION_Y, SCALE_X, SCALE_Y, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, X, Y, Z。
设置重复和周期
下面的代码渐出20%。我们可以加上周期或者重复
ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(tvLabel, "scaleX", 1.0f, 2.0f);
scaleAnim.setDuration(3000);
scaleAnim.setRepeatCount(ValueAnimator.INFINITE);
scaleAnim.setRepeatMode(ValueAnimator.REVERSE);
scaleAnim.start();
设置插补
不管什么时候我们定义一个属性动画,我么 都要考虑动画变化的速率。换句话说,我们不仅仅要变,还要考虑怎么变,往那边。下面是指定了一个 TimeInterpolator
ObjectAnimator moveAnim = ObjectAnimator.ofFloat(v, "Y", 1000);
moveAnim.setDuration(2000);
moveAnim.setInterpolator(new BounceInterpolator());
moveAnim.start();
一些常用的插补器
AccelerateInterpolator:慢慢的出现然后加速
BounceInterpolator:弹回
DecelerateInterpolator:快速出现然后减速
LinearInterpolator:匀速的
还有一些其他的插补器可以供你参考
监听动画的生命周期
你可以加上 AnimatorListenerAdapter去管理动画周期的时间,比如说onAnimationStart 或者onAnimationEnd
ObjectAnimator anim = ObjectAnimator.ofFloat(v, "alpha", 0.2f);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(MainActivity.this, "End!", Toast.LENGTH_SHORT).show();
}
});
anim.start();
多个动画
我们可以给ObjectAnimator 对象加上多个动画共同执行
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(tvLabel, "scaleX", 1.0f, 2.0f)
.setDuration(2000),
ObjectAnimator.ofFloat(tvLabel, "scaleY", 1.0f, 2.0f)
.setDuration(2000),
ObjectAnimator.ofObject(tvLabel, "backgroundColor", new ArgbEvaluator(),
/*Red*/0xFFFF8080, /*Blue*/0xFF8080FF)
.setDuration(2000)
);
set.start();
下面还有一些animator sets
// Define first set of animations
ObjectAnimator anim1 = ObjectAnimator.ofFloat(tvLabel, "scaleX", 2.0f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(tvLabel, "scaleY", 2.0f);
AnimatorSet set1 = new AnimatorSet();
set1.playTogether(anim1, anim2);
// Define second set of animations
ObjectAnimator anim3 = ObjectAnimator.ofFloat(v, "X", 300);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(v, "Y", 300);
AnimatorSet set2 = new AnimatorSet();
set2.playTogether(anim3, anim4);
// Play the animation sets one after another
AnimatorSet set3 = new AnimatorSet();
set3.playSequentially(set1, set2);
set3.start();
// Create two animations to play together
ObjectAnimator bounceAnim = ...;
ObjectAnimator squashAnim = ...;
// Construct set 1 playing together
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).with(squashAnim);
// Create second animation to play after
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(view1, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
// Play bouncer before fade
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();