天天看點

Android 動畫詳細總結

目錄:

1.android動畫導圖 2.View Animation(視圖動畫) (1)Tween Animation(補間動畫) (2)Frame Animation(幀動畫) 3.Property Animation(屬性動畫) (1)屬性動畫概述 (2)相關類繼承關系 (3)相關類、接口概述導圖 (4)ValueAnimator類 (5)ObjectAnimator類 (6)TypeEvaluator接口相關類引入 (7)xml實作屬性動畫 4.Interpolator(插值器) (1)插值器的作用與概述 (2)常見的插值器 (3)xml中設定插值器 (4代碼中設定插值器 5.AnimationSet與AnimatorSet(動畫集合) 6.自定義TypeEvaluator和屬性實作屬性動畫總結案例

1.android動畫導圖

Android 動畫詳細總結

通過導圖我們可以知道動畫的實作可以通過java代碼和xml檔案兩種方式實作,下面再學習每種動畫的時候 我們試着用兩種方法取實作。

2.View Animation(視圖動畫)

2.1 Tween Animation補間動畫

(1)透明度(alpha)動畫實作=淡入淡出動畫 布局檔案(兩種實作方式一緻):

<?xml version="1.0" encoding="utf-8"?>              <LinearLayout              xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:orientation="vertical"              tools:context="com.example.animation.MainActivity">                  <ImageView              android:id="@+id/alphaImage"              android:src="@drawable/weimei"              android:layout_width="wrap_content"              android:layout_height="wrap_content" />                  </LinearLayout>           

java代碼實作:

package com.example.animation;                  import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.view.animation.AlphaAnimation;              import android.view.animation.Animation;              import android.widget.ImageView;                  public class MainActivity extends AppCompatActivity {              private ImageView alphaImage;                  @Override              protected void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_main);              //綁定布局控件              alphaImage = (ImageView) findViewById(R.id.alphaImage);                  //執行個體化透明度動畫,設定透明度從1f~0f              AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);              //設定動畫時間              alphaAnimation.setDuration(2000);              //設定動畫結束後保持結束時的動畫狀态              //alphaAnimation.setFillAfter(true);              //設定結束時儲存開始時的狀态              alphaAnimation.setFillBefore(true);              //設定插值器              //alphaAnimation.setInterpolator();              //設定動畫循環次數              alphaAnimation.setRepeatCount(2);              //設定循環模式REVERSE|RESTART|其他              alphaAnimation.setRepeatMode(Animation.REVERSE);              //将動畫設定到控件              alphaImage.startAnimation(alphaAnimation);              }              }           

xml檔案實作: 在src/anim/下建檔案alpha_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <set xmlns:android="http://schemas.android.com/apk/res/android">              <alpha              android:duration="2000"              android:fromAlpha="1.0"              android:toAlpha="0.0"              android:fillBefore="true"              android:repeatCount="2"              android:repeatMode="reverse"              />              </set>              <!--              常用屬性設定:              android:fromAlpha="1.0"//開始時候的透明度              android:toAlpha="0.0"//結束的透明度              android:fillAfter="true"//動畫結束後保持最後的狀态              android:fillBefore="true"//動畫結束後回複一開始的狀态              android:fillEnabled=""//效果同fillBefore              android:interpolator=""//設定動畫的插值器              android:startOffset=""//設定動畫開始後延遲時長度,機關毫秒              android:detachWallpaper //設定是否在桌面上運作              android:repeatCount=""///設定動畫運作次數              android:zAdjustment="normal|top|bottom"//設定動畫在運作時在Z軸的位置              android:repeatMode="reverse|restart"//設定重複模式,倒叙|從頭              -->           

java代碼引入

package com.example.animation;                  import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.view.animation.Animation;              import android.view.animation.AnimationUtils;              import android.widget.ImageView;                  public class MainActivity extends AppCompatActivity {              private ImageView alphaImage;                  @Override              protected void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_main);              //綁定布局控件              alphaImage = (ImageView) findViewById(R.id.alphaImage);                  //xml定義動畫,然後通過AnimationUtils.loadAnimation(Context context, int id)加載              Animation alphaAnimationX = AnimationUtils.loadAnimation(              MainActivity.this, R.anim.alpha_animation);              //開啟動畫              alphaImage.startAnimation(alphaAnimationX);              }              }           

上面是通過java代碼和xml布局兩種方式進行動畫實作,下面就隻使用xml布局實作了,有興趣的朋友可以試試用java代碼取實作 ,在實際開發中其實也比較推薦xml布局檔案吧,畢竟它比較簡潔直覺,易于管理,同時也滿足邏輯與布局分離的分層架構思想。

(2)旋轉(rotate)動畫實作 在src/anim/下建檔案rotate_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <set xmlns:android="http://schemas.android.com/apk/res/android">              <rotate              android:fromDegrees="0"              android:toDegrees="180"              android:pivotX="0"              android:pivotY="0"              android:fillAfter="true"              android:repeatCount="4"              android:repeatMode="reverse"              android:duration="2000"/>              </set>              <!--              常用屬性設定:              android:fromDegrees="0"//旋轉開始角度              android:toDegrees="180"//旋轉結束角度              android:pivotX="50%"//旋轉中心點X坐标,百分數表示(控件長度*百分數)的的位置,如果是數值表示從控件左上角開始計算,              android:pivotY="50%"//旋轉中心點Y坐标              android:fillAfter="true"//動畫結束後保持最後的狀态              android:fillBefore="true"//動畫結束後回複一開始的狀态              android:fillEnabled=""//效果同fillBefore              android:interpolator=""//設定動畫的插值器              android:startOffset=""//設定動畫開始後延遲時長度,機關毫秒              android:detachWallpaper //設定是否在桌面上運作              android:repeatCount=""///設定動畫運作次數              android:zAdjustment="normal|top|bottom"//設定動畫在運作時在Z軸的位置              android:repeatMode="reverse|restart"//設定重複模式,倒叙|從頭              -->           

java代碼引入

package com.example.animation;                  import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.view.animation.Animation;              import android.view.animation.AnimationUtils;              import android.widget.ImageView;                  /**              * Created by elimy on 2016-10-20.              */              public class RotateActivity extends AppCompatActivity {              private ImageView rotateImage;              @Override              protected  void onCreate(Bundle savedInstanceState){              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_rotate);              //綁定控件              rotateImage = (ImageView) findViewById(R.id.rotateImage);              //加載xml動畫檔案              Animation rotateAnimation = AnimationUtils.loadAnimation(              RotateActivity.this,R.anim.rotate_animation);              //啟動動畫              rotateImage.startAnimation(rotateAnimation);                  }              }           

(3)縮放(scale)動畫實作

java代碼引入部分的代碼和上面的都一緻,就不重複貼出來了,下面是xml布局實作縮放動畫的代碼 在src/anim/下建檔案scale_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <set xmlns:android="http://schemas.android.com/apk/res/android">              <scale              android:fromXScale="1.0"              android:fromYScale="1.0"              android:toXScale="0.5"              android:toYScale="0.5"              android:pivotX="50%"              android:pivotY="50%"              android:fillAfter="true"              android:repeatCount="4"              android:repeatMode="reverse"              android:duration="2000"/>              </set>              <!--              常用屬性設定:              android:fromXScale=""//初始的x軸縮放比例              android:fromYScale=""//初始的y軸縮放比例              android:toXScale=""//結束時的x軸縮放比例              android:toYScale=""//結束時的y軸縮放比例              android:pivotX="50%"//縮放中心點X坐标,百分數表示(控件長度*百分數)的的位置,如果是數值表示從控件左上角開始計算,              android:pivotY="50%"//縮放中心點Y坐标              android:fillAfter="true"//動畫結束後保持最後的狀态              android:fillBefore="true"//動畫結束後回複一開始的狀态              android:fillEnabled=""//效果同fillBefore              android:interpolator=""//設定動畫的插值器              android:startOffset=""//設定動畫開始後延遲時長度,機關毫秒              android:detachWallpaper //設定是否在桌面上運作              android:repeatCount=""///設定動畫運作次數              android:zAdjustment="normal|top|bottom"//設定動畫在運作時在Z軸的位置              android:repeatMode="reverse|restart"//設定重複模式,倒叙|從頭              -->           

(4)位移(translate)動畫實作(xml布局實作)

在src/anim/下建檔案translate_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <set xmlns:android="http://schemas.android.com/apk/res/android">              <translate              android:fromXDelta="0"              android:fromYDelta="0"              android:toXDelta="50%p"              android:toYDelta="50%p"              android:fillAfter="true"              android:repeatCount="4"              android:repeatMode="reverse"              android:duration="2000"/>              </set>              <!--              常用屬性設定:              注意:android:toYDelta="50%p"中的50%p是指目前動畫控件從初始位置移動到初始位置y坐标+父控件搞的50%的位置,其他也是同理              android:fromXDelta="0"//位移起始點x坐标,相對于目前執行動畫的view來計算,值類型和之前android:pivotX|android:pivotY相同              android:fromYDelta="0"//位移起始點y坐标              android:toXDelta="0"//位移結束點x坐标              android:toYDelta="800"//位移結束點x坐标              android:fillAfter="true"//動畫結束後保持最後的狀态              android:fillBefore="true"//動畫結束後回複一開始的狀态              android:fillEnabled=""//效果同fillBefore              android:interpolator=""//設定動畫的插值器              android:startOffset=""//設定動畫開始後延遲時長度,機關毫秒              android:detachWallpaper //設定是否在桌面上運作              android:repeatCount=""///設定動畫運作次數              android:zAdjustment="normal|top|bottom"//設定動畫在運作時在Z軸的位置              android:repeatMode="reverse|restart"//設定重複模式,倒叙|從頭              -->           
2.2)Frame Animation(幀動畫)

(1)建立animation-list檔案位于res/drawable/下面frame_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <animation-list xmlns:android="http://schemas.android.com/apk/res/android"              android:oneshot="false">              <item android:drawable="@drawable/mingxing1020_copy"              android:duration="1000"/>              <item android:duration="1000"              android:drawable="@drawable/weimei"/>              <item android:duration="1000"              android:drawable="@drawable/weimei1020"/>              <item android:duration="1000"              android:drawable="@drawable/xiaoqingxin1020"/>              <item android:drawable="@drawable/xingkong1020"              android:duration="1000"/>              </animation-list>              <!--              android:oneshot="false"//表示動畫是否隻執行一次              android:duration="1000"//表示每個item項顯示持續的時間              android:drawable="@drawable/xingkong1020"//訓示顯示的圖檔              -->           

(2)java代碼啟動動畫FrameActivity.java

package com.example.animation;                  import android.graphics.drawable.AnimationDrawable;              import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.view.animation.Animation;              import android.view.animation.AnimationUtils;              import android.widget.ImageView;                  /**              * Created by elimy on 2016-10-20.              */              public class FrameActivity extends AppCompatActivity {              private ImageView frameImage;              private AnimationDrawable frameAnimation;              @Override              protected  void onCreate(Bundle savedInstanceState){              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_frame);              //綁定控件              frameImage = (ImageView) findViewById(R.id.frameImage);              //設定控件的背景資源              frameImage.setBackgroundResource(R.drawable.frame_animation);              //通過控件擷取背景資源執行個體化AnimationDrawable              frameAnimation = (AnimationDrawable) frameImage.getBackground();              }                  @Override              protected void onResume() {              super.onResume();              //開啟frame動畫,我把動畫啟動發在onResume()中沒有放在onCreate()中避免在activity剛啟動時圖檔還未完全依附到window上面              frameAnimation.start();              }              }           

PS:上面的動畫實作都比較簡單,隻要簡單了解API的作用和參數含義基本就能實作,接下來我們看看比較複雜同時也挺了不起 的動畫,屬性動畫

3.Property Animation(屬性動畫)

(1)屬性動畫概述

              一句話就是:通過改變對象的屬性來實作動畫效果,是在API 11後引入的。

(2)相關類繼承關系
Android 動畫詳細總結
(3)相關類、接口概述導圖
Android 動畫詳細總結
(4)ValueAnimator類

4.1)常用方法

public static ValueAnimator ofInt(int... values)//通過設定多個int類型的參數值,是實作在多個值之間的平滑過渡                  public ValueAnimator()//無參構造方法                  public static ValueAnimator ofArgb(int... values) //設定argb多參數值的平滑過渡,與ofInt(int... values)類似                  public static ValueAnimator ofFloat(float... values)//設定float類型的參數值,效果和ofInt(int... values)類似                  //TypeEvaluator為自定義的類型電腦,Object... values指定自定義類型變化值              //和ofInt(int... values)中的參數類似,隻不過這裡的類型不是int類型而是自己定義的類型。              public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values)                  public ValueAnimator setDuration(long duration) //設定動畫持續時間                  public void addUpdateListener(AnimatorUpdateListener listener)//實作屬性更新監聽                  public void setRepeatCount(int value) //設定重複次數                  public void setRepeatMode(int value)//設定重複模式 RESTART|REVERSE,和補間動畫類似                  public void setEvaluator(TypeEvaluator value) //設定目前動畫的類型電腦                  public void setIntValues(int... values) //設定多個int類型參數值,作用和ofInt(int... values)中的參數相同               

4.2)使用案例 (4.2.1)布局檔案activity_property.xml

<?xml version="1.0" encoding="utf-8"?>              <RelativeLayout              xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:layout_margin="@dimen/activity_horizontal_margin"              tools:context="com.example.animation.MainActivity">                  <Button              android:id="@+id/propertyBtn"              android:text="點我點我"              android:layout_width="wrap_content"              android:layout_height="wrap_content" />                  </RelativeLayout>           

(4.2.2)動畫實作類PropertyActivity.java

package com.example.animation;                  import android.animation.Animator;              import android.animation.ValueAnimator;              import android.content.DialogInterface;              import android.graphics.drawable.AnimationDrawable;              import android.os.Build;              import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.util.Log;              import android.view.View;              import android.view.animation.AnimationSet;              import android.widget.Button;              import android.widget.ImageView;                  /**              * Created by elimy on 2016-10-20.              */              public class PropertyActivity extends AppCompatActivity implements View.OnClickListener {              private Button propertyBtn;              @Override              protected  void onCreate(Bundle savedInstanceState){              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_property);              propertyBtn = (Button) findViewById(R.id.propertyBtn);              propertyBtn.setOnClickListener(this);              }                  @Override              public void onClick(View v) {              //通過ofInt()靜态方法初始化ValueAnimator并指定變化參數集合              //ValueAnimator animator = ValueAnimator.ofInt(0,3,4,5);              ValueAnimator animator = ValueAnimator.ofFloat(0f,3f,4f,5f);                  //下面兩行與ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,3f,4f,5f)效果相同              /*        ValueAnimator animator = new ValueAnimator();              animator.setFloatValues(0f,3f,4f,5f);*/              //animator.setIntValues(0,3,4,5);                  //設定屬性動畫持續時間              animator.setDuration(1000);              //啟動動畫              animator.start();              //設定屬性更新的監聽              animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {              @Override              public void onAnimationUpdate(ValueAnimator animation) {              //擷取目前更新後的參數值              Float value = (Float) animation.getAnimatedValue();              //列印              Log.d("animation value = ",value+"");              }              });              //設定屬性動畫開始、結束、取消、重複的監聽              animator.addListener(new Animator.AnimatorListener() {              @Override              public void onAnimationStart(Animator animation) {                  }                  @Override              public void onAnimationEnd(Animator animation) {                  }                  @Override              public void onAnimationCancel(Animator animation) {                  }                  @Override              public void onAnimationRepeat(Animator animation) {                  }              });              //api 19及以上可以設定屬性動畫暫停、重新運作監聽器              if (Build.VERSION.SDK_INT>=19) {              animator.addPauseListener(new Animator.AnimatorPauseListener() {              @Override              public void onAnimationPause(Animator animation) {                  }                  @Override              public void onAnimationResume(Animator animation) {                  }              });              }              }              }           

(4.2.3)Log列印結果:

10-24 09:35:47.300 6227-6227/com.example.animation D/animation?value?=: 0.0              10-24 09:35:47.318 6227-6227/com.example.animation D/animation?value?=: 0.006416112              10-24 09:35:47.358 6227-6227/com.example.animation D/animation?value?=: 0.05540237              10-24 09:35:47.397 6227-6227/com.example.animation D/animation?value?=: 0.15211639              10-24 09:35:47.454 6227-6227/com.example.animation D/animation?value?=: 0.49047062              10-24 09:35:47.498 6227-6227/com.example.animation D/animation?value?=: 0.859424              10-24 09:35:47.524 6227-6227/com.example.animation D/animation?value?=: 1.0058107              10-24 09:35:47.534 6227-6227/com.example.animation D/animation?value?=: 1.1526973              10-24 09:35:47.549 6227-6227/com.example.animation D/animation?value?=: 1.3180195              10-24 09:35:47.565 6227-6227/com.example.animation D/animation?value?=: 1.4924154              10-24 09:35:47.582 6227-6227/com.example.animation D/animation?value?=: 1.6643976              10-24 09:35:47.599 6227-6227/com.example.animation D/animation?value?=: 1.8549659              10-24 09:35:47.615 6227-6227/com.example.animation D/animation?value?=: 2.0530782              10-24 09:35:47.633 6227-6227/com.example.animation D/animation?value?=: 2.2459195              10-24 09:35:47.649 6227-6227/com.example.animation D/animation?value?=: 2.457043              10-24 09:35:47.665 6227-6227/com.example.animation D/animation?value?=: 2.6739907              10-24 09:35:47.686 6227-6227/com.example.animation D/animation?value?=: 2.882946              10-24 09:35:47.699 6227-6227/com.example.animation D/animation?value?=: 3.0364745              10-24 09:35:47.746 6227-6227/com.example.animation D/animation?value?=: 3.186596              10-24 09:35:47.755 6227-6227/com.example.animation D/animation?value?=: 3.2653484              10-24 09:35:47.766 6227-6227/com.example.animation D/animation?value?=: 3.3447697              10-24 09:35:47.782 6227-6227/com.example.animation D/animation?value?=: 3.4199276              10-24 09:35:47.801 6227-6227/com.example.animation D/animation?value?=: 3.5              10-24 09:35:47.815 6227-6227/com.example.animation D/animation?value?=: 3.5800724              10-24 09:35:47.833 6227-6227/com.example.animation D/animation?value?=: 3.6552303              10-24 09:35:47.850 6227-6227/com.example.animation D/animation?value?=: 3.7346513              10-24 09:35:47.866 6227-6227/com.example.animation D/animation?value?=: 3.8134034              10-24 09:35:47.883 6227-6227/com.example.animation D/animation?value?=: 3.886711              10-24 09:35:47.900 6227-6227/com.example.animation D/animation?value?=: 3.9635255              10-24 09:35:47.917 6227-6227/com.example.animation D/animation?value?=: 4.039018              10-24 09:35:47.932 6227-6227/com.example.animation D/animation?value?=: 4.1086698              10-24 09:35:47.949 6227-6227/com.example.animation D/animation?value?=: 4.1809855              10-24 09:35:47.967 6227-6227/com.example.animation D/animation?value?=: 4.25136              10-24 09:35:47.984 6227-6227/com.example.animation D/animation?value?=: 4.315641              10-24 09:35:48.000 6227-6227/com.example.animation D/animation?value?=: 4.381678              10-24 09:35:48.018 6227-6227/com.example.animation D/animation?value?=: 4.445201              10-24 09:35:48.032 6227-6227/com.example.animation D/animation?value?=: 4.502528              10-24 09:35:48.050 6227-6227/com.example.animation D/animation?value?=: 4.5606604              10-24 09:35:48.066 6227-6227/com.example.animation D/animation?value?=: 4.6157675              10-24 09:35:48.085 6227-6227/com.example.animation D/animation?value?=: 4.6647296              10-24 09:35:48.100 6227-6227/com.example.animation D/animation?value?=: 4.7135253              10-24 09:35:48.115 6227-6227/com.example.animation D/animation?value?=: 4.7588606              10-24 09:35:48.132 6227-6227/com.example.animation D/animation?value?=: 4.7982516              10-24 09:35:48.149 6227-6227/com.example.animation D/animation?value?=: 4.8365097              10-24 09:35:48.169 6227-6227/com.example.animation D/animation?value?=: 4.8709564              10-24 09:35:48.187 6227-6227/com.example.animation D/animation?value?=: 4.899807              10-24 09:35:48.199 6227-6227/com.example.animation D/animation?value?=: 4.9265847              10-24 09:35:48.215 6227-6227/com.example.animation D/animation?value?=: 4.9492946              10-24 09:35:48.234 6227-6227/com.example.animation D/animation?value?=: 4.966894              10-24 09:35:48.250 6227-6227/com.example.animation D/animation?value?=: 4.9815326              10-24 09:35:48.266 6227-6227/com.example.animation D/animation?value?=: 4.991946              10-24 09:35:48.282 6227-6227/com.example.animation D/animation?value?=: 4.9978614              10-24 09:35:48.299 6227-6227/com.example.animation D/animation?value?=: 5.0	           
(5)ObjectAnimator類

5.1)常用方法

//和ValueAnimation的ofInt()方法類似,隻是參數還需要傳入動畫目标對象(target)和動畫改變的屬性(propertyName)              public static ObjectAnimator ofInt(Object target, String propertyName, int... values)                  //和上面類似,隻是在設定參數值的時候提供二維數組參數輸入              public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values)                  //設定目标的argb參數值變化              public static ObjectAnimator ofArgb(Object target, String propertyName, int... values)                  //和ValueAnimation的ofFloat()方法類似,參數傳遞方式和該類的ofInt()方法類似就不重複了              public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)                  //類似ofMultiInt()方法              public static ObjectAnimator ofMultiFloat(Object target, String propertyName,float[][] values)                  //這個方法建構一個自定義的屬性值和自定義的類型電腦的屬性動畫              public static ObjectAnimator ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)                  //這3個方法是分别對應ofInt()、ofFloat()、ofObject()中屬性值得設定              public void setIntValues(int... values)              public void setFloatValues(float... values)              public void setObjectValues(Object... values)                  //設定插值器,不設定預設為線性插值器              public void setInterpolator(TimeInterpolator value)                  //設定動畫作用的對象              public void setTarget(@Nullable Object target)                  //啟動屬性動畫              public void start()           

5.2)使用案例(實作視圖動畫中的透明度(alpha)動畫) (5.2.1)核心Java類ObjectAnimationActivity.java

package com.example.animation;                  import android.animation.Animator;              import android.animation.ObjectAnimator;              import android.animation.ValueAnimator;              import android.os.Build;              import android.os.Bundle;              import android.support.v7.app.AppCompatActivity;              import android.util.Log;              import android.view.View;              import android.widget.Button;              import android.widget.ImageView;                  /**              * Created by elimy on 2016-10-20.              */              public class ObjectAnimationActivity extends AppCompatActivity implements View.OnClickListener {              private Button objectAnimBtn;              private ImageView imageView;              @Override              protected  void onCreate(Bundle savedInstanceState){              super.onCreate(savedInstanceState);              setContentView(R.layout.activity_object_animation);              //綁定控件              objectAnimBtn = (Button) findViewById(R.id.objectAnimBtn);              imageView = (ImageView) findViewById(R.id.imageView);              //設定點選監聽              objectAnimBtn.setOnClickListener(this);              }              /*              * 監聽實作              * */              @Override              public void onClick(View v) {              /*        //構造方法實作初始化ObjectAnimator              ObjectAnimator objectAnimator = new ObjectAnimator();              //設定屬性值              objectAnimator.setPropertyName("alpha");              //設定透明度變化值,從不透明到透明再到不透明              objectAnimator.setFloatValues(1f,0f,1f);              //設定動畫對象              objectAnimator.setTarget(imageView);              */              //初始化ObjectAnimator,并設定動畫主體,變化屬性,以及變化參數集;下面一步相當于前面4步              ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,"alpha",1f,0f,1f);              // ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,"scaleX",1f,2f,1f,0.5f);                  //設定插值器(線性插值器)              objectAnimator.setInterpolator(new LinearInterpolator());                  //設定的動畫時間              objectAnimator.setDuration(5000);              //啟動動畫              objectAnimator.start();              }              }           

(5.2.2)布局檔案activity_object_animation.xml

<?xml version="1.0" encoding="utf-8"?>              <RelativeLayout              xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:tools="http://schemas.android.com/tools"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:layout_margin="@dimen/activity_horizontal_margin"              tools:context="com.example.animation.MainActivity">                  <Button              android:id="@+id/objectAnimBtn"              android:text="點我點我"              android:layout_width="wrap_content"              android:layout_height="wrap_content" />                  <ImageView              android:id="@+id/imageView"              android:src="@drawable/weimei1020"              android:layout_centerInParent="true"              android:layout_width="wrap_content"              android:layout_height="wrap_content" />              </RelativeLayout>           

(5.2.3)總結延伸: 可能有朋友看了上面的案例以後會有疑問,這裡面objectAnimator.setPropertyName("alpha")和ofFloat(imageView,"alpha",1f,0f,1f) 中的參數到底可以設定哪些呢?我随便寫個A B C行不行呢?當然是不行了,那我們應該去哪兒找呢?ok,這個就需要看我們的操作對象類和 它的父類了,在這裡就是ImageView和ImageView的父類View類,你去看這兩個類的時候你可能會發現許多get/set方法,比如:public void setAlpha(int alpha) public void setScaleX(float scaleX), public void setRotationX(float rotationX)等等,其實我們這裡設定的屬性參數就來源于這些set方法的參數 ,大家都知道屬性動畫就是改變屬性的值進而實作的動畫,而這些set方法剛好就是設定對象的屬性,我想說到這裡應該恍然大悟了吧。

ps:上面的案例實作了視圖動畫中的透明度(alpha)動畫,朋友們可以試着去找相關屬性實作旋轉、移動、縮放動畫。

(6)TypeEvaluator接口相關類引入

TypeEvaluator中文是類型計算的意思。有朋友可能會說之前屬性動畫都沒涉及什麼類型計算啊,為啥這個時候冒個類型計算出來,其實之前也有涉及 類型的計算隻是它隐藏在源代碼中,也可以說在之前的代碼中類型計算google官方已經為我們做了,其實在源碼中Google已經為我們做了一些簡單的類型計算,比如 IntEvaluator、ArgbEvaluator、FloatEvaluator等,是以我們就沒管。但是大家想想,如果我們自己想自定義一些屬性動畫,然後屬性的類型又不是上面的int,float,argb等 類型我們該咋辦呢?ok,google大牛們就知道有人不喜歡被束縛非要自己寫,是以也就有了public static ObjectAnimator ofObject(Object target, String propertyName,  TypeEvaluator evaluator,Object... values)這個方法,是不是突然發現裡面有個TypeEvaluator類型的參數需要我們傳入?對,就是這個方法這個方法是一個靈活性最大的 方法,它支援我們自己去定義屬性,定義動畫,定義類型計算方法。 ok,在明白了我們有自定義屬性動畫的需求之後,大家可能又會想類型計算(TypeEvaluator)到底又起了哪些作用呢?我們來看看IntEvaluator的源代碼

package android.animation;                  /**               * This evaluator can be used to perform type interpolation between <code>int</code> values.               */              public class IntEvaluator implements TypeEvaluator<Integer> {                      public Integer evaluate(float fraction, Integer startValue, Integer endValue) {                      int startInt = startValue;                      return (int)(startInt + fraction * (endValue - startInt));                  }              }           

源碼注釋大概是說這個電腦可以用來計算int值之間的類型插值。不是很懂,我了解的意思是這個IntEvaluator類用來計算從startValue到endValue的實時過渡變化值,也就是 某個時間點的值是多少。可能又有夥伴開始疑問了裡面的startValue和endValue是我們傳進去的,那fraction參數值是哪兒來的呢?這個值和開始值、結束值和變化速率有關,而 變化速率和我們的插值器TimeInterpolator有關,後面再來說,現在我們隻要知道fraction是來自插值器(Interpolator)計算的結果,它表示變化的完成度,這個時候fraction * (endValue - startInt) 就表示完成了多少值,然後再加上startInt就表示目前的值了。

(7)xml實作屬性動畫(以實作上面的透明度動畫為例)

步驟: 1.在res目錄下建立animator目錄,在animator目錄下建立屬性動畫檔案alpha_property_animator.xml

<?xml version="1.0" encoding="utf-8"?>              <objectAnimator              xmlns:android="http://schemas.android.com/apk/res/android"              android:duration="5000"              android:propertyName="alpha"              android:valueFrom="1"              android:valueTo="0"              android:repeatCount="2"              android:repeatMode="reverse"              android:valueType="floatType">                  </objectAnimator>                  <!--标簽類型有:<set> <animator> <objectAnimator>              其中<set>對應AnimatorSet  <animator>對應valueAnimator              <objectAnimator>對應ObjectAnimator              -->                  <!--              标簽通用屬性設定:              android:duration=""//動畫持續時間              android:startOffset=""//設定執行動畫之前等待的時間              android:repeatCount=""//設定動畫執行的次數              android:repeatMode=""//設定動畫重複執行的模式 restart(從頭開始重複)|reverse(反方向執行)              android:valueFrom=""//設定動畫開始的值              android:valueTo=""//動畫結束的值              android:valueType=""//動感畫類型 intType/floatType              android:interpolator=""//設定動畫速率變化,也就是我們設定的動畫插值器              -->                  <!--              <objectAnimator>标簽特有屬性:              android:propertyName=""//設定要改變的屬性的名字              -->                  <!--              <set>标簽屬性:              android:ordering=""//設定動畫執行順序 together(同時執行) sequentially(按順序執行)              -->	           

2.Java代碼使用xml屬性動畫檔案

package com.example.animation;                  import android.animation.Animator;              import android.animation.AnimatorInflater;              import android.animation.ObjectAnimator;              import android.os.Bundle;              import android.support.annotation.Nullable;              import android.support.v7.app.AppCompatActivity;              import android.view.View;              import android.view.animation.Animation;              import android.widget.Button;              import android.widget.ImageView;                  /**              * Created by elimy on 2016-12-07.              */              public class AlphaPropertyAnimatorActivity extends AppCompatActivity {                  private Button xmlPropBtn;              private ImageView imageView;                  @Override              protected void onCreate(@Nullable Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setContentView(R.layout.x_alpha_property);                  //初始化控件              xmlPropBtn= (Button) findViewById(R.id.xmlPropBtn);              imageView= (ImageView) findViewById(R.id.image);                  //設定點選監聽              xmlPropBtn.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {              //加載佈局檔案中的動畫檔案              ObjectAnimator xmlAlphaAnim= (ObjectAnimator) AnimatorInflater.loadAnimator(AlphaPropertyAnimatorActivity.this,              R.animator.alpha_property_animator);              //設定屬性動畫對象              xmlAlphaAnim.setTarget(imageView);              //設定啟動屬性動畫              xmlAlphaAnim.start();              }              });                  }              }           

4.Interpolator(插值器)

(1)插值器的作用與概述

插值器主要作用就是控制動畫從開始到結束之間的變化快慢和運動軌迹,變化快慢也可以說是動畫變化的速率,就像實體當中的運動一樣,有加速運動,有減速運動以及 勻速運動,而這裡的插值器就是控制動畫變化速率和變化軌迹的,這樣說應該明白了許多。

(2)常見的插值器
AccelerateDecelerateInterpolator//動畫開始和結束變化慢,中間變化快              AccelerateInterpolator//開始比較慢,然後慢慢加速              AnticipateInterpolator//開始的時候向後然後向前甩              AnticipateOvershootInterpolator//開始的時候向後然後向前甩一定值後傳回最後的值              BounceInterpolator//動畫結束時彈起              CycleInterpolator//動畫循環播放,速率沿着正弦曲線              DecelerateInterpolator//開始快後面慢              LinearInterpolator//勻速變化              OvershootInterpolator//向前甩一定值然後再回到原來的位置              PathInterpolator//路徑插值器           
(3)xml中設定插值器
android:interpolator="@android:anim/accelerate_decelerate_interpolator"           
(4代碼中設定插值器
        //Java代碼實作加入插值器                       xmlAlphaAnim.setInterpolator(new BounceInterpolator());	           

5.AnimationSet與AnimatorSet(動畫集合)

(1)AnimationSet: 主要針對于視圖外觀的動畫實作,通常調用animationSet.addAnimation(animation)設定多個動畫集合在一起, 但不能實作動畫的播放順序 (2)AnimatorSet: 不同于AnimationSet,AnimatorSet可以通過playSequentially(),playTogether(), before() with() after()等函數實作動畫的順序組合執行,同時它主要實作視圖view的内部屬性 改變。

6.自定義TypeEvaluator和屬性實作屬性動畫總結案例

(1)自定義ColorEvaluator.java

package com.example.animation;                  import android.animation.IntEvaluator;              import android.animation.TypeEvaluator;              import android.util.Log;                  /**              * Created by elimy on 2016-12-08.              */              public class ColorEvaluator implements TypeEvaluator {                  //定義并初始化運作時的RGB值              private int currentRed=-1;              private int currentGreen=-1;              private int currentBlue=-1;                  @Override              public Object evaluate(float fraction, Object startValue, Object endValue) {                  //将object強制類型轉換為string類型              String startColor= (String) startValue;              String endColor= (String) endValue;              //将初始RGB值分開計算              /*              * 這裡Integer.parseInt(startColor.substring(1,3),16)中的前一個參數我想              * 大多數小夥伴都能看懂,但是後面的16是啥意思呢,我想大家還是大概猜到了,它其實              * 就是“進制”,這裡需要吧截取的字元串轉換成16進制的int值              * */              int startR=Integer.parseInt(startColor.substring(1,3),16);              int startG=Integer.parseInt(startColor.substring(3,5),16);              int startB=Integer.parseInt(startColor.substring(5,7),16);                      //将結束RGB值分開計算              int endR=Integer.parseInt(endColor.substring(1,3),16);              int endG=Integer.parseInt(endColor.substring(3,5),16);              int endB=Integer.parseInt(endColor.substring(5,7),16);                  //diff計算內插補點              int diffR=Math.abs(endR-startR);              int diffG=Math.abs(endG-startG);              int diffB=Math.abs(endB-startB);              int diffColor=diffR+diffG+diffB;                  //計算目前運作時的RGB值              if (currentRed!=endR){              currentRed=getCurrentColor(startR,endR,diffColor,0,fraction);                  }else if (currentGreen!=endG){              currentGreen=getCurrentColor(startG,endG,diffColor,diffR,fraction);                  }else if (currentBlue!=endB){              currentBlue=getCurrentColor(startB,endB,diffColor,diffR+diffG,fraction);                  }                  String currentColor="#"+getHexString(currentRed)              +getHexString(currentGreen)+getHexString(currentBlue);                  //初始化              return currentColor;              }              /*              * 将十進制轉換成十六進制              * */              private String getHexString(int value){              String hexStr=Integer.toHexString(value);              if (hexStr.length()==1){              hexStr="0"+hexStr;              }              return hexStr;              }              /*              * startColor:開始顔色值              * endColor:結束顔色值              * diffColor:RGB顔色值差              * offset:目前計算值偏移              * fraction:完成度,與插值器有關              * */              private int getCurrentColor(int startColor,int endColor,int diffColor,int offset,float fraction){              int currentColor;              //如果開始顔色值小于結束顔色值              if (endColor>startColor){              currentColor= (int) (startColor+(fraction*diffColor-offset));              //如果目前顔色值大于了結束顔色值,則将目前顔色值置為結束顔色值              if (currentColor>endColor){              currentColor=endColor;              }              }else {              currentColor=(int)(startColor-(fraction*diffColor-offset));              if (currentColor<endColor){              currentColor=endColor;              }              }              return currentColor;              }              }           

(2)自定義的view,DrawOvalView.java

package com.example.animation;                  import android.content.Context;              import android.graphics.Canvas;              import android.graphics.Color;              import android.graphics.Paint;              import android.graphics.RectF;              import android.util.AttributeSet;              import android.view.View;                  /**              * Created by elimy on 2016-12-09.              */              public class DrawOvalView extends View {                  private  Paint paint;              private String color;                  public String getColor() {              return color;              }              /*              * 需要改變自定義圓的顔色就必須實作get set方法,屬性動畫的本質是改變對象的屬性              * 而要實作屬性改變後更新UI就出現了下面invalidate()的調用              * */              public void setColor(String color) {              this.color = color;              paint.setColor(Color.parseColor(color));              invalidate();              }                  /*              * 帶一個參數的構造方法              * */              public DrawOvalView(Context context) {              super(context);              }              /*              *帶兩個參數的構造函數,在DrawOvalView執行個體化的時候會對畫筆進行初始化操作              * 如果這裡不初始化設定畫筆顔色的話最終出現的view預設為黑色              * */              public DrawOvalView(Context context, AttributeSet attrs) {                  super(context, attrs);              paint = new Paint();              paint.setColor(Color.parseColor("#0000FF"));              }                  /*              * 繼承view,重載onDraw()方法實作自定義view的繪制              * */              @Override              protected void onDraw(Canvas canvas) {              super.onDraw(canvas);                  // paint.setColor(Color.parseColor("#f8aba6"));              paint.setStrokeWidth(5);              paint.setStrokeCap(Paint.Cap.ROUND);              //設置填充              paint.setStyle(Paint.Style.FILL);              //設定繪制圓              RectF rectF= new RectF(200,200,400,400);                  canvas.drawOval(rectF,paint);              }              }           

(3)主布局Java類實作屬性動畫的應用

package com.example.animation;                  import android.animation.Animator;              import android.animation.ObjectAnimator;              import android.graphics.Color;              import android.graphics.Paint;              import android.os.Bundle;              import android.support.annotation.Nullable;              import android.support.v7.app.AppCompatActivity;              import android.view.View;              import android.view.animation.LinearInterpolator;              import android.widget.Button;              import android.widget.TextView;                  /**               * Created by elimy on 2016-12-09.               */              public class CustomEvaluatorActivity extends AppCompatActivity {                      private DrawOvalView oval;                  private Button color_bt;                  @Override                  protected void onCreate(@Nullable Bundle savedInstanceState) {                      super.onCreate(savedInstanceState);                      setContentView(R.layout.custom_evaluator);                      //綁定空間                      oval= (DrawOvalView) findViewById(R.id.oval);                      color_bt= (Button) findViewById(R.id.color_bt);                      //設定監聽                      color_bt.setOnClickListener(new View.OnClickListener() {                          @Override                          public void onClick(View v) {                              //設定動畫                              ObjectAnimator animator=ObjectAnimator.ofObject(oval,"color",new ColorEvaluator(),"#0000FF", "#FF0000");                              //設置動畫執行時長                              animator.setDuration(10000);                              //設定線性插值器,顔色線性變化                              animator.setInterpolator(new LinearInterpolator());                              //啟動動畫                              animator.start();                          }                      });                          }                      }           

參考: http://www.cnblogs.com/wondertwo/p/5327586.html http://blog.csdn.net/guolin_blog/article/details/43816093