作者@恺风Wei

Frame by frame和Layout动画只需通过XML定义就可以实现动画,而view动画较为复杂,当更为灵活,通过对Animation类的继承,对transformation matrix(转变矩阵)的控制,对view实施动画效果。

View显示是通过transformation matrix,包括像素坐标、颜色等等。通过重新定义基于时间的transformation matrix,就可以得到动画效果,并将使用这个新的transformation matrix来画view。在Android中,如果我们对view注册一个anmiation对象,就可以获得view的transformation matrix,这个animation对象有一个回调函数获得当前的matrix,小例子讲演示这个过程。

小例子效果

小例子如图所示,和Layout动画不同,本次,我们是将ListView作为一个View整体进行动画,而不是针对里面的item。

Pro Android学习笔记(一零八):2D动画(3):view动画的小例子_view animation

步骤一:向View注册一个Animation对象

要获得View的transformation matric,我们需要先向view注册一个Animation对象。实现这个对象的自定义类为ViewAnimation。相关代码如下:

… ….  
    Button button = (Button)findViewById(R.id.button1);
     button.setOnClickListener(new OnClickListener(){  
         @Override 
        public void onClick(View v) { 
            animate(); 
        };  
 ……    


 private void animate(){ 
     ListView lv = (ListView) findViewById(R.id.list_view_2); 
     lv.startAnimation(new ViewAnimation()); //向view注册Animation对象}

步骤二:自定义Animation

自定义的Animation继承android.view.animation.Animation。

public class ViewAnimation extends Animation {      
   //initialize()是告知尺寸的回调函数,包括view的长宽,parent容器的长宽(本来为LinearLayout的长宽),同时也是初始化动画参数的地方。
    public void initialize(int width, int height, int parentWidth, int parentHeight) {         super.initialize(width, height, parentWidth, parentHeight);
         setDuration(2500);   
        //动画结束后,会保持在动画的最后形态,在本例,这个设置并没什么影响,如果view从位置A移动位置B,如果setFileAfter(true)则动画结束后,会停留在位置B,如果设置flase(缺省值),则会回到位置A。
         setFillAfter(true);    
        setInterpolator(new LinearInterpolator());     } 

     @Override //动画设置在applyTransformation(),Android会不断地调用appalyTransformation()来同步动画,每次参数1 interpolatedTime会变化,从0到1,表示动画进展,1表示动画的最后。参数2 t表示transformation,可以从中获取当前的transformation matrix,我们的目的就是改变它,根据进展程度(interpolatedTime不同),具有不同的值。当View在paint的时候,新的matrix起作用,形成动画效果。 
         final Matrix matrix = t.getMatrix(); 
         Log.i("WEI","--------------------------"); 
         Log.i("WEI","interpolated time = " + interpolatedTime); 
         Log.i("WEI","transformation = " + t); 
         Log.i("WEI","matrix = " + matrix); 
         //关于Matrix可以参见android.graphics.Matrix类的参考,下面的setScale是设置x方向和y方向的伸缩值,本例直接使用interpolatedTime,从开始的0到最后的1,使得view逐渐扩大。
         matrix.setScale(interpolatedTime, interpolatedTime); 
        Log.i("WEI","matrix = " + matrix); 
    } 
     
 }

如果我们在applyTransformation()中跟中两个参数的值,如下:

Pro Android学习笔记(一零八):2D动画(3):view动画的小例子_Android_02

从LogCat中可以看到:

1)interpolatedTime从0不断地增加到1,而transformation含有alpha和matrix两个属性;

2)获取的matrix并不是当前显示的属性,所获取值一样,估计是view无动画时的显示属性;

3)matrix是一个3×3的矩阵,对照reference,MSCALE_X=0,MSCALE_Y =4,为对应matrix的位置。



小例子代码在:

Pro Android学习:2D动画小例子