周末下雨,拿这个时间来学习了下动画,对Android4.0.3主菜单里面实现的那个摆动挺好奇的,学习了下,大体的效果已经实现了,这篇文章小马就写下具体的实现,代码中间小马试了很多东西,也加了很多注释,希望大家不要嫌啰嗦,多试了下多学点动画,吼吼,不多说废话,老样子,先看效果,再看分解的代码,分解效果图如下:

  先贴下文件目标结构,方便查看在文件中是如何引用动画资源的,截图如下:

Android插值器、动画、分解详解,实现View摆动效果_第1张图片

  1 View内容渐变效果图一:

   

Android插值器、动画、分解详解,实现View摆动效果_第2张图片

  2 View内容渐变效果图二:

   

Android插值器、动画、分解详解,实现View摆动效果_第3张图片

  3 View动画刚开始时效果图如下:

   

Android插值器、动画、分解详解,实现View摆动效果_第4张图片

  4 View动画播放到一半时效果图如下:

   

Android插值器、动画、分解详解,实现View摆动效果_第5张图片

  5 View动画播放结束时效果图如下:

   

Android插值器、动画、分解详解,实现View摆动效果_第6张图片

  好了,大体的效果看完了,下面小马来分解下代码,大家不用担心看不懂,小马会在最后将此DEMO源码放在附件中,供大家学习交流:

一:先看下主布局文件,里面没什么重要的东西,但为了完整还是贴下:

   
   
   
   
  1. xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="fill_parent" 
  4.     android:layout_height="fill_parent" 
  5.     android:orientation="vertical" > 
  6.      
  7.     <Button  
  8.         android:id="@+id/button" 
  9.         android:layout_width="fill_parent" 
  10.         android:layout_height="wrap_content" 
  11.         android:text="播放ListView动画" 
  12.         /> 
  13.     <ListView 
  14.         android:id="@+id/listview" 
  15.         android:layout_width="fill_parent" 
  16.         android:layout_height="fill_parent" 
  17.         android:layoutAnimation="@anim/list_layout_controller" 
  18.         android:persistentDrawingCache="animation|scrolling" /> 
  19. LinearLayout> 

二:下面来看下主控制类代码,如下:   

   
   
   
   
  1. package com.xiaoma.listviewanimation.demo; 
  2.  
  3. import android.app.Activity; 
  4. import android.graphics.Camera; 
  5. import android.graphics.Matrix; 
  6. import android.os.Bundle; 
  7. import android.view.View; 
  8. import android.view.View.OnClickListener; 
  9. import android.view.animation.AccelerateDecelerateInterpolator; 
  10. import android.view.animation.AccelerateInterpolator; 
  11. import android.view.animation.Animation; 
  12. import android.view.animation.AnticipateInterpolator; 
  13. import android.view.animation.AnticipateOvershootInterpolator; 
  14. import android.view.animation.BounceInterpolator; 
  15. import android.view.animation.CycleInterpolator; 
  16. import android.view.animation.DecelerateInterpolator; 
  17. import android.view.animation.LinearInterpolator; 
  18. import android.view.animation.OvershootInterpolator; 
  19. import android.view.animation.Transformation; 
  20. import android.widget.ArrayAdapter; 
  21. import android.widget.Button; 
  22. import android.widget.ListView; 
  23.  
  24. /** 
  25.  * @Title: ListViewAnimationDemoActivity.java 
  26.  * @Package com.xiaoma.listviewanimation.demo 
  27.  * @Description: ListView控件动画学习测试 
  28.  * @author MZH 
  29.  *  
  30.  * 因为小马也处于学习的阶段,我会尽可能在在自己代码中多加注释,供大家学习交流,也 
  31.  * 供自己以后有用到的时候直接看代码,不重翻API,所以注释多了大家别嫌烦,吼吼 
  32.  *  
  33.  */ 
  34. public class ListViewAnimationDemoActivity extends Activity implements 
  35.         OnClickListener { 
  36.  
  37.     private ListView listview; 
  38.     private Button btn; 
  39.  
  40.     /** Called when the activity is first created. */ 
  41.     @Override 
  42.     public void onCreate(Bundle savedInstanceState) { 
  43.         super.onCreate(savedInstanceState); 
  44.         setContentView(R.layout.main); 
  45.         init(); 
  46.     } 
  47.  
  48.     /** 
  49.      * 初始化方法实现 
  50.      */ 
  51.     private void init() { 
  52.         btn = (Button) findViewById(R.id.button); 
  53.         btn.setOnClickListener(this); 
  54.         String items[] = { "还记得""那一年""那一天""有个人""爱过我"
  55.                 "洗刷刷""爱拉拉""哇吼吼""咔酷伊""咔哇伊""哦吼吼""小马果"}; 
  56.         listview = (ListView) findViewById(R.id.listview); 
  57.         //适配器我就用最简单的,要用复杂的,大家可以自定义适配器 
  58.         ArrayAdapter adapter = new ArrayAdapter
  59.                 getApplicationContext(), android.R.layout.simple_list_item_1, 
  60.                 items); 
  61.         listview.setAdapter(adapter); 
  62.     } 
  63.  
  64.     /** 
  65.      * 布局内所有点击事件监听 
  66.      */ 
  67.     @Override 
  68.     public void onClick(View v) { 
  69.         // 因为只有一个按钮,小马就直接写个if简单的判断下了,多个老规矩用分支判断 
  70.         if (v.getId() == R.id.button) { 
  71.             //开始播放ListView动画 
  72.             startPlayAnimation(); 
  73.         } 
  74.     } 
  75.  
  76.     /** 
  77.      * 开始播放ListView动画方法实现 
  78.      */ 
  79.     private void startPlayAnimation() { 
  80.         // ListViewAnimationChange为矩阵控制类 
  81.         listview.startAnimation(new ListViewAnimationChange()); 
  82.     } 
  83.  
  84.     /** 
  85.      * @Title: ListViewAnimationChange.java 
  86.      * @Package com.xiaoma.listviewanimation.demo 
  87.      * @Description: ListView控件的矩阵内部控制类 
  88.      * @author MZH 
  89.      * 在这个地方讲下,要自行控制屏幕矩阵的话必须实现现在两个方法 
  90.      */ 
  91.     private class ListViewAnimationChange extends Animation { 
  92.  
  93.         @Override 
  94.         public void initialize(int width, int height, int parentWidth, 
  95.                 int parentHeight) { 
  96.  
  97.             // 将动画播放时间设置为5秒 
  98.             setDuration(5000); 
  99.             // 设置缩放完成后,效果不消失 
  100.             setFillAfter(true); 
  101.  
  102.             // 设置线性插值器,这个地方new出来的对象跟在scale.xml中的插值器没什么区别,也可以用别的 
  103.              
  104.             /** 
  105.              * 顺带着讲下在2D动画中常用的插值器吧,小马先给自己及大伙提醒下:插值器,就是告诉Android,播放动画时 
  106.              * 是从快到慢还是从慢到快,从左到右的旋转还是其它的方式的动画,刚开始很怕这个词,试了下效果,其实不太吓人... 
  107.              * 吼吼,类型如下面的八种,跟scale.xml或alpha.xml中使用的插值器一样的,只是写的形式不一样而已 
  108.              *  
  109.              */ 
  110.  
  111.             /** 
  112.              * 所有的插值器都实现Interpolator接口中的 getInterpolation(float input)方法,好奇的朋友 
  113.              * Ctrl跟进下....只注意一点,插值器不能同时set多个,不然最前面的会被覆盖,即:无效果.. 
  114.              * new AccelerateDecelerateInterpolator();  
  115.              * new AccelerateInterpolator();  
  116.              * new CycleInterpolator(1.0f);  
  117.              * new DecelerateInterpolator();  
  118.              * new AnticipateInterpolator();  
  119.              * new AnticipateOvershootInterpolator();  
  120.              * new BounceInterpolator();  
  121.              * new OvershootInterpolator();  
  122.              * new LinearInterpolator(); 
  123.              * 与以上几种插值器相对应的方法在xml文件中的使用方式大家可以自动ALT+/试下,换汤不换药 
  124.              */ 
  125.              
  126.             //下面是小马试的效果,好奇的朋友们可以打开效果试下,小马不一一解释 
  127.             // setInterpolator(new LinearInterpolator()); 
  128.             // setInterpolator(new CycleInterpolator(1.0f) ); 
  129.             // setInterpolator(new AccelerateDecelerateInterpolator()); 
  130.             // setInterpolator(new DecelerateInterpolator()); 
  131.              
  132.              
  133.             /** 
  134.              * 这两个好玩就选了,这个效果类似于Android 4.0的那个左右摆动..效果可以自己打开注释试下.. 
  135.              * 要用自己效果的可以重新改下矩阵的控制 
  136.              */ 
  137.             setInterpolator(new AnticipateOvershootInterpolator());  
  138.             //setInterpolator(new OvershootInterpolator());  
  139.             super.initialize(width, height, parentWidth, parentHeight); 
  140.         } 
  141.          
  142.         /** 
  143.          * 这个重写是控制矩阵中关键的一步 
  144.          * 介绍一个参数:interpolatedTime 安卓系统在模拟动画时会反复的调用这个方法 
  145.          * 所以这个值是一直变化的,从0-1变化.... 
  146.          * 这个方法就是在某一个时间点上将动画添加到指定的控件上 
  147.          */ 
  148.         @Override 
  149.         protected void applyTransformation(float interpolatedTime, 
  150.                 Transformation t) { 
  151.             super.applyTransformation(interpolatedTime, t); 
  152.  
  153.             /* 
  154.              * final Matrix matrix = t.getMatrix(); 
  155.              * matrix.setScale(interpolatedTime, interpolatedTime); 
  156.              * matrix.preTranslate(-50f, -50f); matrix.postTranslate(50f, 50f); 
  157.              */ 
  158.             // matrix.setRotate(45f); 
  159.             // matrix.setTranslate(40f,50f); 
  160.              
  161.             /** 
  162.              * Camera小马犯的错:导相机包...大家注意下就可以了, 
  163.              * 我们应该导入graphics包 
  164.              */ 
  165.             Camera camera = new Camera(); 
  166.             //取得屏幕矩阵对象 
  167.             final Matrix matrix = t.getMatrix(); 
  168.             camera.save(); 
  169.             /** 
  170.              * 下面方法中的参数大家自己CTRL跟下,小马不一一解说, 
  171.              * 不跟进的自己改改看下效果就知道是什么意思了.. 
  172.              */ 
  173.             camera.translate(0.0f, 0.0f, (1300 - 1300.0f * interpolatedTime)); 
  174.             camera.rotateY(360 * interpolatedTime); 
  175.             camera.getMatrix(matrix); 
  176.             //设置矩阵播放动画前的位置.原点为:0,0 
  177.             matrix.preTranslate(-50f, -50f); 
  178.             //设置矩阵播放完动画后的位置 
  179.             matrix.postTranslate(50f, 50f); 
  180.             camera.restore(); 
  181.             // 如果用了以下的效果,则上面Camera做的矩阵变换将被覆盖 
  182.             // matrix.setScale(interpolatedTime, interpolatedTime); 
  183.         } 
  184.     } 

  这个地方小马提醒下,在主控制类中,最重要的是那具自定义的动画类,它控制着VIEW的所有动画,如:插值器...2D渲染等,具体的看代码及注释部分的代码即可:   

四:下面来看下用来关联View控件与动画的动画控制器代码:

   
   
   
   
  1. xml version="1.0" encoding="utf-8"?>