零零碎碎的东西总是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无意中发现了这个每日一道面试题,想了想如果只是简单地去思考,那么不仅会收效甚微,甚至难一点的题目自己可能都懒得去想,坚持不下来。所以不如把每一次的思考、理解以及别人的见解记录下来。不仅加深自己的理解,更要激励自己坚持下去。
补间动画
补间动画是根据我们设置好的view起始形态与终止形态,通过插值器与duration(时长)自动计算出中间view的平滑变化而实现动画效果。
补间动画有TranslateAnimation(平移)、ScaleAnimation(缩放)、RotateAnimation(旋转)、AlphaAnimatio(渐变)四个类,这些只是很基本的四种动画效果,如果我们需要在此基础上更为复杂的动画效果,可以继承这四个类进行装饰。
一般情况下我们都是在xml文件中定义补间动画,属性设置大致有起始值、终止值、时长(duration)、插值(interpolator,即动画的变化速度,加速、减速、匀速、抛物线速度)四个属性,四种动画效果的标签—translate、scale、rotate、alpha。具体属性设置及意义如下:
<!--平移-->
<translate
<!--水平方向、竖直方向初始的view位置-->
android:fromXDelta="0%"
android:fromYDelta="0%"
<!--水平方向、竖直方向终止点的view位置-->
android:toXDelta="100%"
android:toYDelta="100%"
<!--动画持续时间-->
android:duration="@integer/animation_duration"/>
<!--缩放-->
<scale
<!--水平方向、竖直方向初始的view缩放大小-->
android:fromXScale="0.5"
android:fromYScale="0.5"
<!--水平方向、竖直方向终止点的view缩放大小-->
android:toXScale="1.0"
android:toYScale="1.0"
<!--指定缩放中心点的坐标-->
android:pivotX="50%"
android:pivotY="50%"
<!--动画持续时间-->
android:duration="@integer/animation_duration"/>
<!--旋转-->
<rotate
<!--起始旋转角度-->
android:fromDegrees="0"
<!--终止旋转角度-->
android:toDegrees="1800"
<!--旋转中心点-->
android:pivotY="50%"
android:pivotX="50%"
<!--动画持续时间-->
android:duration="@integer/animation_duration"/>
<!--渐变-->
<alpha
<!--起始透明度-->
android:fromAlpha="1"
<!--终止透明度-->
android:toAlpha="0.5"
<!--动画持续时间-->
android:duration="@integer/animation_duration"/>
java代码设置
Animation animation = AnimationUtils.loadAnimation(this, R.anim.activity_open_enter);
animation.start();
imageView.setAnimation(animation);
属性动画
属性动画更为强大。补间动画只能自定义两个关键帧在旋转、位移、缩放、透明度四个方面的变化,而属性动画可以定义任何属性的变化。另外,补间动画只能对UI组件执行动画,但属性动画几乎可以对任何对象执行动画(不管它是否在屏幕上显示)。
属性动画有三个关键的类—ValueAnimation、ObjectAnimation、AnimationSet
ValueAnimation
属性动画主要的时间引擎,负责计算各个帧的属性值。它定义了属性动画绝大部分核心功能,包括计算各帧的属性值,负责处理更新事件、按属性类型值控制计算规则等。
ValueAnimation创建动画步骤:
- 使用ValueAnimation的静态方法ofInt()、ofFloat、ofObject()创建ValueAnim实例。
- 通过setXxx()设置动画持续时间、插值方式、重复次数等
- 调用start方法启动动画
- 上面三个步骤仅仅是计算出了各个帧的属性值,我们需要注册AnimationUpdateListener监听器,在监听器中监听ValueAnimation计算出来的值的改变,应用到指定对象上
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
valueAnimator.setDuration(1000 * 3);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获得变化的属性值
int time = (int) animation.getAnimatedValue();
...//对指定对象进行属性值更新操作
}
});
一般来说,ValueAnimation、本身并不显示任何动画,它更像是一个数值计算器。通过ofXxx方法指定计算类型,通过steXxx方法设置计算中值的变化方式,产生一段有规律的数字,让开发者自己为指定对象动态的设置属性。
ObjectAnimation
ObjectAnim类继承了ValueAnimation类,可以直接将ValueAnimation计算出来的值应用到指定对象的指定属性上。
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "translationX", 0,500);
animator.setDuration(2000);
animator.start();
ofFloat方法与ValueAnimation中不同的是第一个参数是执行动画的对象,第二个参数是需要操作的属性,后面是一个可变长数组,表示属性值的起始于终止值。
第二个参数需要操作的属性在第一个参数对象中需要有get和set方法。ObjectAnimation内部是通过反射机制获得set方法动态的设置对象属性。可以直接使用的的属性有:
- translationX、translationY:这两个属性作为一种增量来控制着View对象从它布局容器的左上角坐标开始的位置。
- rotation、rotationX、rotationY:这三个属性控制着View对象围绕它的支点进行2D和3D的旋转。
- scaleX和scaleY:这两个属性控制着View对象围绕它的支点进行2D缩放。
- pivotX和pivotY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,该支点的位置就是View对象的中心点。
- alpha:它表示View对象的alpha透明度。
- x、y:这是两个简单的实用的属性,它描述了View对象在它的容器中最终的位置。
AnimationSet
那么多炫酷的动画,当然不可能只是靠单一一个ObjectAnimation来实现的,这就需要多个ObjectAnimation进行组合,就需要AnimationSet类了。
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0,500);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationX", 0,500);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "translationX", 0,500);
ObjectAnimator animator4 = ObjectAnimator.ofFloat(imageView, "translationX", 0,500);
animatorSet.play(animator1).after(animator2).with(animator3).before(animator4);
animatorSet.setDuration(2000);
animatorSet.start();
AnimationSet的play方法表示播放当前动画,其余还有组合方法:
- after(Animator anim) : 将现有动画插入到传入的动画之后执行。
- after(long delay):将现有的动画延迟指定的毫秒后执行。
- before(Animator anim):将现有的动画插入到传入的动画之前执行。
- with(Animator anim):将现有的动画和传入的动画同时执行。
- playSequentially(Animator… items):表示按顺序执行这些动画.
- playTogether(Animator… items);表示这些动画一起执行.
区别
- 属性动画在补间动画的基础上定义了更多高级的功能
- 补间动画只能对UI组件执行动画,但属性动画几乎可以对任何对象执行动画,不管它是否显示在屏幕上
- 最重要的一点:补间动画只是在视图层次进行了改变,对象的属性并没有改变。而属性动画是真正的改变了属性值,根据设置动态的属性值实现动画效果。一个很好的例子就是一个图片在采用补间动画进行平移后,点击平移后的图片是不会有点击事件发生,点击平移前的位置会有点击事件发生(虽然执行动画后这里看起来什么也没有)。而属性动画则会对新位置响应点击事件。