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:动画从开始到结束,变化率是一个线性的过程。