一.前言 1.三种动画的关系 
2.三种动画的继承关系 
二.逐帧动画(Frame Animation) 简单讲就是把几个静态的图片(放在res/drawable/路径下)快速播放形成动画,实现的方式有 Xml方式 或者 Java代码,官方推荐使用 Xml 方式。 
效果展示: 
1. Xml方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="utf-8"?> <animation-list  xmlns:android ="http://schemas.android.com/apk/res/android"      android:oneshot ="true" >          <item  android:drawable ="@drawable/campfire01"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire02"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire03"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire04"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire05"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire06"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire07"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire08"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire09"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire10"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire11"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire12"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire13"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire14"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire15"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire16"  android:duration ="200" />      <item  android:drawable ="@drawable/campfire17"  android:duration ="200" />  </animation-list > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public  class  MainActivity  extends  AppCompatActivity           AnimationDrawable animationDrawable;     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  ImageView imageView = findViewById(R.id.frame_image_view);                  animationDrawable = (AnimationDrawable) imageView.getDrawable();     }          public  void  start_frame_animation (View view)           animationDrawable.start();     }          public  void  stop_frame_animation (View view)           animationDrawable.stop();     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout  xmlns:android ="http://schemas.android.com/apk/res/android"      xmlns:app ="http://schemas.android.com/apk/res-auto"      xmlns:tools ="http://schemas.android.com/tools"      android:layout_width ="match_parent"      android:layout_height ="match_parent"      tools:context =".MainActivity"      android:orientation ="vertical" >     <ImageView         android:id="@+id/frame_image_view"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:src="@drawable/fire_frame_animation"         android:scaleType="fitXY"         />     <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="start"         android:layout_alignParentStart="true"         android:layout_marginStart="20dp"         android:layout_alignParentBottom="true"         android:layout_marginBottom="20dp"         android:onClick="start_frame_animation"         />     <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="stop"         android:layout_alignParentEnd="true"         android:layout_marginEnd="20dp"         android:layout_alignParentBottom="true"         android:layout_marginBottom="20dp"         android:onClick="stop_frame_animation"         /> </RelativeLayout > 
2.Java代码 
Xml方式使用的 item,java代码使用public void addFrame(@NonNull Drawable frame, int duration)方法达到相同的效果。 
Xml方式直接在Xml布局文件里面给ImageView设置动画Xml文件(fire_frame_animation.xml)作为背景,java代码使用public void setImageDrawable(@Nullable Drawable drawable)方法设置AnimationDrawable的对象为背景。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public  class  MainActivity  extends  AppCompatActivity           AnimationDrawable animationDrawable;     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  animationDrawable = new  AnimationDrawable();                           int [] resID = {R.drawable.campfire01,R.drawable.campfire02,                 R.drawable.campfire03, R.drawable.campfire04,                 R.drawable.campfire05,R.drawable.campfire06,                 R.drawable.campfire07,R.drawable.campfire08,                 R.drawable.campfire09,R.drawable.campfire10,                 R.drawable.campfire11,R.drawable.campfire12,                 R.drawable.campfire13,R.drawable.campfire14,                 R.drawable.campfire15,R.drawable.campfire16,                 R.drawable.campfire17};         for  (int  i = 0 ; i < resID.length; i++) {             animationDrawable.addFrame(getResources().getDrawable(resID[i],null ),100 );         }                  ImageView imageView = findViewById(R.id.frame_image_view);         imageView.setImageDrawable(animationDrawable);     }          public  void  start_frame_animation (View view)           animationDrawable.start();     }          public  void  stop_frame_animation (View view)           animationDrawable.stop();     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout  xmlns:android ="http://schemas.android.com/apk/res/android"      xmlns:app ="http://schemas.android.com/apk/res-auto"      xmlns:tools ="http://schemas.android.com/tools"      android:layout_width ="match_parent"      android:layout_height ="match_parent"      tools:context =".MainActivity" >     <ImageView         android:id="@+id/frame_image_view"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:scaleType="fitXY"         />     <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="start"         android:layout_alignParentStart="true"         android:layout_marginStart="20dp"         android:layout_alignParentBottom="true"         android:layout_marginBottom="20dp"         android:onClick="start_frame_animation"         />     <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="stop"         android:layout_alignParentEnd="true"         android:layout_marginEnd="20dp"         android:layout_alignParentBottom="true"         android:layout_marginBottom="20dp"         android:onClick="stop_frame_animation"         /> </RelativeLayout > 
三.补间动画(Tween Animation) 补间动画就是指开发者指定动画的开始、动画的结束的”关键帧”,而动画变化的”中间帧”由系统计算,并补齐。 
补间动画有四种: 
位移 TranslateAnimation
缩放 ScaleAnimation
旋转 RotateAnimation
透明度 AlphaAnimation
 
1. Xml方式 
系统默认不会在 res 文件夹下面创建 anim 文件夹,我们需要手动创建 anim 文件夹。我们的动画xml文件就存放在这里面。 我们使用的AnimationUtils的public static Animation loadAnimation(Context context, @AnimRes int id)方法加载我们的动画xml文件。 四种方式共有的属性:  
1 2 3 4 5 6 7 8 9 10 android:duration="3000"      android:startOffset="1000"   android:fillBefore="true"                                                            android:fillAfter="false"    android:fillEnabled="true"     android:repeatMode="restart"   android:repeatCount="0"        android:interpolator = @[package :]anim/interpolator_resource  
① 位移 TranslateAnimation 
Translate独有的属性: 
1 2 3 4 android:fromXDelta="0"     android:toXDelta="100"     android:fromYDelta="0"     android:toYDelta="100"     
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 //动画 translate_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <translate  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fromXDelta ="0"      android:toXDelta ="100"      android:fromYDelta ="0"      android:toYDelta ="100"      android:duration ="1000"      android:repeatCount ="1"      android:repeatMode ="restart"      /> 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  TranslateActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_translate);                  final  View view = findViewById(R.id.translate_view);                  final  Animation translate = AnimationUtils.loadAnimation(this , R.anim.translate_animation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(translate);             }         });     } } 
运行效果: 
② 缩放 ScaleAnimation 
Scale独有的属性: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 android:fromXScale="1"       android:toXScale="1.5"       android:fromYScale="1"       android:toYScale="1.5"             android:pivotX="100%"        android:pivotY="100%"           
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 //动画 scale_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <scale  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fromXScale ="1"      android:toXScale ="1.5"      android:fromYScale ="1"      android:toYScale ="1.5"      android:pivotX ="100%"      android:pivotY ="100%"      android:duration ="1000"      android:repeatCount ="1"      android:repeatMode ="restart"      /> 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  ScaleActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_scale);                  final  View view = findViewById(R.id.translate_view);                  final  Animation scale = AnimationUtils.loadAnimation(this , R.anim.scale_animation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(scale);             }         });     } } 
运行效果: 
③ 旋转 RotateAnimation 
Rotate独有的属性: 
1 2 3 4 5 6 7 8 9 10 android:fromDegrees="0"      android:toDegrees="270"      android:pivotX="100%"        android:pivotY="100%"           
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 //动画 rotate_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <rotate  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fromDegrees ="0"      android:toDegrees ="90"      android:pivotX ="100%"      android:pivotY ="100%"      android:duration ="1000"      android:repeatCount ="1"      android:repeatMode ="restart"      /> 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  class  RotateActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_rotate);                  final  View view = findViewById(R.id.translate_view);                  final  Animation rotate = AnimationUtils.loadAnimation(this , R.anim.rotate_animation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(rotate);             }         });     } } 
运行效果: 
④ 透明度 AlphaAnimation 
Alpha独有的属性: 
1 2 android:fromAlpha="1.0"   android:toAlpha="0.0"     
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 //动画 alpha_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <alpha  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fromAlpha ="1"      android:toAlpha ="0.5"      android:duration ="1000"      android:repeatCount ="1"      android:repeatMode ="restart"      /> 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  AlphaActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_alpha);                  final  View view = findViewById(R.id.translate_view);                  final  Animation alpha = AnimationUtils.loadAnimation(this , R.anim.alpha_animation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(alpha);             }         });     } } 
运行效果: 
⑤ 组合 
关于android:fillBefore 和android:fillEnabled的使用。首先说结论,如果fillEnabled为false,那么不管fillBefore取何值,都是fillBefore为true的效果。 
1.两个效果的实现: 
View先在原位置从0.5倍放大到2倍,然后在从原位置的45度旋转到720度。效果图和代码如下所示: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?xml version="1.0" encoding="utf-8"?> <set  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fillBefore ="false"      android:fillAfter ="false"      >     <scale         android:fromXScale="0.5"         android:toXScale="2.0"         android:fromYScale="0.5"         android:toYScale="2.0"         android:pivotX="50%"         android:pivotY="50%"         android:duration="3000"         android:fillEnabled="false"         />     <rotate         android:fromDegrees="45"         android:toDegrees="720"         android:pivotX="50%"         android:pivotY="50%"         android:duration="2000"         android:startOffset="3000"         android:fillEnabled="true"         /> </set > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  SetActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_set);                  final  View view = findViewById(R.id.translate_view);                  final  Animation scale = AnimationUtils.loadAnimation(this , R.anim.set_animation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(scale);             }         });     } } 
初始状态为View偏90度,大小为View本身大小的一半,在接下来的1秒内变为View本身大小的2倍,然后,再在接下来的2秒内旋转到720度的位置,最后变为View本身的大小。运行效果如下:(其实就是第一个效果中的Xml代码去掉全部的android:fillEnabled=”true”和android:fillBefore=”false”,其他不变,就会达成我们当前所描述的效果) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?xml version="1.0" encoding="utf-8"?> <set  xmlns:android ="http://schemas.android.com/apk/res/android"      android:fillAfter ="false"      >     <scale         android:fromXScale="0.5"         android:toXScale="2.0"         android:fromYScale="0.5"         android:toYScale="2.0"         android:pivotX="50%"         android:pivotY="50%"         android:duration="3000"         />     <rotate         android:fromDegrees="45"         android:toDegrees="720"         android:pivotX="50%"         android:pivotY="50%"         android:duration="2000"         android:startOffset="3000"         /> </set > 
2.两种运行效果的解释: 
除去全部的android:fillEnabled=”true”和android:fillBefore=”false”之后,fillEnabled默认为false,fillBefore默认为true。而fillEnabled为false、fillBefore为any相当于fillEnabled为true且fillBefore为true,也就是动画开始时,动画属性要设置成给与的样式,View偏90度,大小为View本身大小的一半。
除去全部的android:fillEnabled=”true”和android:fillBefore=”false”之前,我们一开始设置动画集合的fillBefore为false,缩放动画的fillEnabled为false,也就是说初始的缩放状态是大小为View本身大小的一半。旋转动画的fillEnabled为true,动画集合的fillBefore为false,也就是说初始的旋转状态是View本身的初始值。结合起来就是View不偏转,大小为View本身大小的一半。
 
2.Java代码 java代码主要是使用继承于 Animation 的 TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation,AnimationSet。和 Xml 共有的属性一样,这些类也共有对应的方法(来自父类 Animation): 
1 2 3 4 5 6 7 8 9 10 public  void  setDuration (long  durationMillis)     public  void  setStartOffset (long  startOffset)     public  void  setFillBefore (boolean  fillBefore)                                                                                                      public  void  setFillAfter (boolean  fillAfter)      public  void  setFillEnabled (boolean  fillEnabled)  public  void  setRepeatMode (int  repeatMode)        public  void  setRepeatCount (int  repeatCount)      public  void  setInterpolator (Interpolator i)      
① 位移 TranslateAnimation 
1 2 3 4 5 public  TranslateAnimation (float  fromXDelta, float  toXDelta, float  fromYDelta, float  toYDelta) 
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public  class  TranslateActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_translate);                  final  View view = findViewById(R.id.translate_view);                  final  TranslateAnimation translate = new  TranslateAnimation(0 ,100 ,0 ,100 );                  translate.setDuration(1000 );                  translate.setRepeatCount(1 );                  translate.setRepeatMode(Animation.RESTART);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(translate);             }         });     } } 
运行效果: 
② 缩放 ScaleAnimation 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  ScaleAnimation (float  fromX, float  toX, float  fromY, float  toY,             int  pivotXType, float  pivotXValue, int  pivotYType, float  pivotYValue)       
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public  class  ScaleActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_scale);                  final  View view = findViewById(R.id.translate_view);                  final  ScaleAnimation scale = new  ScaleAnimation(1.0f ,1.5f ,1.0f ,1.5f ,Animation.RELATIVE_TO_SELF,1.0f ,Animation.RELATIVE_TO_SELF,1.0f );                  scale.setDuration(1000 );                  scale.setRepeatCount(1 );                  scale.setRepeatMode(Animation.RESTART);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(scale);             }         });     } } 
运行效果: 
③ 旋转 RotateAnimation 
1 2 3 4 5 6 7 8 9 10 11 12 13 public  RotateAnimation (float  fromDegrees, float  toDegrees, int  pivotXType, float  pivotXValue,             int  pivotYType, float  pivotYValue)    
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public  class  RotateActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_rotate);                  final  View view = findViewById(R.id.translate_view);                  final  RotateAnimation rotate = new  RotateAnimation(0f ,90f ,Animation.RELATIVE_TO_SELF,1.0f ,Animation.RELATIVE_TO_SELF,1.0f );                  rotate.setDuration(1000 );                  rotate.setRepeatCount(1 );                  rotate.setRepeatMode(Animation.RESTART);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(rotate);             }         });     } } 
运行效果: 
④ 透明度 AlphaAnimation 
1 2 3 public  AlphaAnimation (float  fromAlpha, float  toAlpha) 
运行效果的代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public  class  AlphaActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_alpha);                  final  View view = findViewById(R.id.translate_view);                  final  AlphaAnimation alpha = new  AlphaAnimation(1.0f ,0.5f );                  alpha.setDuration(1000 );                  alpha.setRepeatCount(1 );                  alpha.setRepeatMode(Animation.RESTART);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(alpha);             }         });     } } 
运行效果: 
⑤ 组合动画 
1 2 3 AnimationSet                                         public  AnimationSet (boolean  shareInterpolator)       public  void  addAnimation (Animation a)                
运行效果代码以及例子: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public  class  SetActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_set);                  final  View view = findViewById(R.id.translate_view);                  final  AnimationSet animationSet = new  AnimationSet(true );                  animationSet.setFillBefore(false );         animationSet.setFillAfter(false );                  ScaleAnimation scaleAnimation = new  ScaleAnimation(0.5f , 2.0f , 0.5f , 2.0f , Animation.RELATIVE_TO_SELF, 0.5f , Animation.RELATIVE_TO_SELF, 0.5f );         scaleAnimation.setDuration(3000 );         scaleAnimation.setFillEnabled(false );                  RotateAnimation rotateAnimation = new  RotateAnimation(45 , 720 , Animation.RELATIVE_TO_SELF, 0.5f , Animation.RELATIVE_TO_SELF, 0.5f );         rotateAnimation.setDuration(2000 );         rotateAnimation.setFillEnabled(true );         rotateAnimation.setStartOffset(3000 );                  animationSet.addAnimation(scaleAnimation);         animationSet.addAnimation(rotateAnimation);                  findViewById(R.id.start).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   view.startAnimation(animationSet);             }         });     } } 
3.高级使用 ① 监听动画 
Animation类通过监听动画开始 / 结束 / 重复时刻来进行一系列操作,如跳转页面等等。通过在 Java 代码里setAnimationListener()方法设置。 
若采取上述方法监听动画,每次监听都必须重写4个方法。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Animation.setAnimationListener(new  Animation.AnimationListener() {       @Override        public  void  onAnimationStart (Animation animation)                     }       @Override        public  void  onAnimationEnd (Animation animation)                     }        @Override         public  void  onAnimationRepeat (Animation animation)                      } }); 
采用动画适配器AnimatorListenerAdapter,解决实现接口繁琐的问题。 
 
1 2 3 4 5 6 7 8 9 anim.addListener(new  AnimatorListenerAdapter() {       @Override        public  void  onAnimationStart (Animator animation)            }   });   
② Interpolator(插值器) 
Android动画-插值器(Interpolator) 
4.Activity 的切换效果实战 ① 系统预设 
系统已经封装好了淡入淡出、左滑右滑的效果,具体使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Intent intent = new  Intent (this ,Acvtivity.class); startActivity(intent); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); @Override public  void  finish ()     super .finish();     overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);                             } 
实际例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public  class  MainActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         final  Intent intent = new  Intent(this , SecondActivity.class);         findViewById(R.id.fade_animation).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   startActivity(intent);                                                 overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);             }         });         findViewById(R.id.slide_animation).setOnClickListener(new  View.OnClickListener() {             @Override              public  void  onClick (View v)                   startActivity(intent);                                               overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);             }         });     } } 
② 自定义切换效果 
1> 淡入淡出 效果是采用透明度动画(Alpha)。
fade_in.xml(淡入)
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?>   <set  xmlns:android ="http://schemas.android.com/apk/res/android"  >          <alpha             android:duration ="1500"            android:fromAlpha ="0.0"            android:toAlpha ="1.0"  />      </set >   
fade_out.xml(淡出)
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?>   <set  xmlns:android ="http://schemas.android.com/apk/res/android"  >          <alpha             android:duration ="1500"            android:fromAlpha ="1.0"            android:toAlpha ="0.0"  />      </set >   
在Java代码中设置
1 2 3 4 Intent intent = new  Intent(MainActivity.this , SecActivity.class); startActivity(intent); overridePendingTransition(R.anim.fade_in, R.anim.fade_out); 
2> 左右滑动 效果
out_to_left.xml
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set  xmlns:android ="http://schemas.android.com/apk/res/android"      >     <translate         android:duration="500"         android:fromXDelta="0%p"         android:toXDelta="-100%p"          /> </set > 
in_from_right.xml
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set  xmlns:android ="http://schemas.android.com/apk/res/android"      >     <translate         android:duration="500"         android:fromXDelta="100%p"         android:toXDelta="0%p"         /> </set > 
在Java代码中设置效果
1 2 3 4 Intent intent = new  Intent(MainActivity.this , SecActivity.class); startActivity(intent); overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left); 
3> 酷炫的Activity切换动画,打造更好的用户体验 
5.补间动画原理 
四.属性动画(Property Animation) 为什么需要属性动画? 
补间动画 只能够作用在视图View上,即只可以对一个Button、TextView、甚至是LinearLayout、或者其它继承自View的组件进行动画操作,但无法对非View的对象进行动画操作。 
补间动画 没有改变View的属性,只是改变视觉效果。 
补间动画 动画效果单一。 
 
工作原理 
实现方式 
实际开发中,建议使用Java代码实现属性动画:因为很多时候属性的起始值是无法提前确定的(无法使用XML设置),这就需要在Java代码里动态获取。 
XML方式具备重用性,即将通用的动画写到XML里,可在各个界面中去重用它。 
 
1. ValueAnimator学习 实现动画的原理:通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果。如下图: 
详细内容请看:Android动画-ValueAnimator 
2.ObjectAnimator学习 动画的原理: 通过不断控制 值 的变化,再不断 自动 赋给对象的属性,从而实现动画效果。如下图:
详细内容请看:Android动画-ObjectAnimator 
3.插值器(Interpolator)和 估值器(TypeEvaluator) 详细内容请看:
4.属性动画的使用小技巧 详细内容请看:Android动画-属性动画的使用小技巧 
5.ValueAnimator类 & ObjectAnimator 类的区别 对比ValueAnimator类 & ObjectAnimator 类,其实二者都属于属性动画,本质上都是一致的:先改变值,然后 赋值 给对象的属性从而实现动画效果。
区别在于:
ValueAnimator 类是先改变值,然后 手动赋值  给对象的属性从而实现动画;是 间接  对对象属性进行操作; 
ObjectAnimator类是先改变值,然后 自动赋值  给对象的属性从而实现动画;是 直接  对对象属性进行操作; 
参考文章 Android 逐帧动画:关于 逐帧动画 的使用都在这里了! 
Android:这是一份全面 & 详细的补间动画使用教程 
对Animation中的fillAfter,fillBefore,fillEnabled的理解 
Android 动画:手把手带你深入了解神秘的插值器(Interpolator) 
Android:属性动画的核心使用类ValueAnimator学习指南 
Android:手把手带你深入了解神秘的估值器(TypeEvaluator) 
Android 属性动画的ObjectAnimator类学习指南 
Android 动画:这些属性动画的使用小技巧你了解吗 
安卓动画学习(六)–xml实现属性动画