android动画大体分为两种,一种是视图动画,一种是属性动画。
视图动画
Animation动画框架定义了透明度、旋转、位移、缩放几种常见的动画效果,控制的是整个view,实现原理是每次绘制动画视图时View锁在的ViewGroup中的drawChild函数获取该view的Animation中的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算来完成动画帧。如果动画没有完成,就继续调用incalidate()函数,启动下次绘制来驱动动画,从而完成整个动画的绘制。
视图动画使用较简单,提供了AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四种动画方式以及AnimationSet动画集合,可以实现丰富的动画效果,视图动画的优点是效率高、方便使用。但是视图动画同时存在很大的一个缺点是不具有交互性,当某个view发生视图动画后,其响应的位置还依然在动画前的地方,所以视图动画只用来做纯粹的普通动画效果,要避免交互的发生。
透明度动画
AlphaAnimation aa = new AlphaAnimation(0,1) ; //0:初始透明度。1:终止透明度
aa.setDuration(1000);
view.startAnimation(aa);
旋转动画
//0:起始角度,360:终止角度,100:旋转中心X值,100:旋转中心Y值
ra.setDuration(1000);
view.startAnimation(ra);
位移动画
TranslateAnimation ta = new TranslateAnimation(0,200,0,300)
ta.setDuration(1000);
view.startAnimation(ta);
缩放动画
ScaleAnimation sa = new ScaleAnimation(0,2,0,3);
sa.setDuration(1000);
view.startAnimation(sa);
动画集合
AnimationSet as = new AnimationSet(true);
as.setDuration(1000);
as.addAnimation(aa);
as.addAnimation(ta);
as.addAnimation(sa);
view.startAnimation(as);
视图动画亦可以通过添加动画监听接口,对动画过程进行监听,OnAnimationListener.
animation.setAnimationListener
属性动画
在属性动画Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更加精细化的控制,使用多个ObjectAnimator组合到AnimatorSet形成一个动画,ObjectAnimator可以自行驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU的资源消耗,最重要的是,属性动画通过调用属性的get、set方法真实地控制了一个View的属性值,因此强大的属性动画框架,基本可以实现所有的动画效果,在使用ObjectAnimator的时候,要操纵的属性一定得有get和set方法。
通过ObjectAnimator的静态工厂方法,创建一个ObjectAnimator对象
ObjectAnimator oa = ObjectAnimator.ofFloat(view,"translationX",300); //view:要操作的view,“translationX”:要操纵的属性,最后一个是参数
oa.setDuration(300);
oa.start();
PropertyValuesHolder
针对一个对象的多个属性设置动画,可以使用PropertyValuesHolder来实现
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f,0,1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f,0,1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1,pvh2,pvh3).setDuration(1000).start();
动画事件的监听
一个完整的动画具有start、repeat、end、cancel四个过程,通过android提供的接口可以很方便的监听这四个事件。
ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
oa.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
});
AnimatorSet
对于一个对象同时作用多个属性动画效果,除了可以使用PropertyValueHolder实现以外,AnimatorSet亦能实现该效果,并且可以做到更为精确的顺序控制,
ObjectAnimator oa1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(view, "scaleX", 1f,0f,1f);
ObjectAnimator oa3 = ObjectAnimator.ofFloat(view, "scaleY", 1f,0f,1f);
AnimatorSet as = new AnimatorSet();
as.setDuration(1000);
as.playTogether(oa1,oa2,oa3);
as.start();
AnimatorSet通过playTogether()、playSequentially()、animSet.play()、with()、defore()、after()这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。
在XML中使用属性动画
属性动画亦可以直接写在XML文件中
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="2.0"
android:valueType="floatType" >
</objectAnimator>
然后再代码中引用
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
anim.setTarget(view);
anim.start();
布局动画
所谓布局动画即是指作用在ViewGroup上给ViewGroup增加View时添加一个动画过渡效果
最简单的布局动画是在ViewGroup的XML中,使用以下代码来打开布局动画:
android:animateLayoutChanges="true"
通过以上代码,当ViewGroup中添加view时,子view会呈现出逐渐显示的过渡效果,但是效果比较单一且无法自定义。
除此之外,我们还可以通过使用LayoutAnimationController类来自定义一个子View的过渡效果,代码如下所示
ScaleAnimation sa = new ScaleAnimation(0, 500, 0, 500);
sa.setDuration(2000);
LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5f);
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
testLayout.setLayoutAnimation(lac);
Interpolators
插值器是动画中一个非常重要的概念,通过插值器,可以定义动画变换速率,
ObjectAnimator oa = ObjectAnimator.ofFloat(testButton, "translationX",
700);
oa.setInterpolator(new AccelerateInterpolator());
AccelerateInterpolator:动画从开始到结束,变化率是一个加速的过程。
DecelerateInterpolator:动画从开始到结束,变化率是一个减速的过程。
CycleInterpolator:动画从开始到结束,变化率是循环给定次数的正弦曲线。
AccelerateDecelerateInterpolator:动画从开始到结束,变化率是先加速再减速的过程。
LinearInterpolator:动画从开始到结束,变化率是一个线性的过程。