集合動畫AnimationSet
補間動畫有四大類:透明度動畫AlphaAnimation、旋轉動畫RotateAnimation、縮放動畫ScaleAnimation、平移動畫TranslateAnimation,而集合動畫AnimationSet便是用來将幾個補間動畫組裝起來。即在同一時刻,讓某視圖呈現出多種動畫效果,如一邊縮放一邊旋轉。
下面是AnimationSet的常用方法:
addAnimation : 添加動畫。
setFillAfter : 設定是否維持結束畫面。true表示動畫結束後停留在結束畫面,false表示動畫結束後恢複到開始畫面。
setRepeatMode : 設定重播模式。RESTART表示從頭開始,REVERSE表示倒過來開始。
setDuration : 設定動畫的持續時間。
setStartTime : 設定動畫的開始時間。Animation.START_ON_FIRST_FRAME表示目前時間,其他值表示轉換為整型數的時間。一般無需調用該方法,預設就是立即開始播放。
setInterpolator : 設定動畫的插值器。
屬性動畫ObjectAnimator
視圖View有許多屬性,四種補間動畫其實隻用到了六個屬性,分别是alpha、rotation、scaleX、scaleY、translationX、translationY,這六個屬性對應View類的方法是setAlpha、setRotation、setScaleX、setScaleY、setTranslationX、setTranslationY。屬性動畫便是為了突破補間動畫的局限,它讓View所有的公開屬性都能夠實作動畫效果,例如背景顔色、文字顔色等等,隻要設定某屬性的起始值與終止值,即可實作該屬性的動畫漸變。
下面是ObjectAnimator的常用方法:
ofInt : 定義整型屬性的屬性動畫。
ofFloat : 定義浮點型屬性的屬性動畫。
ofObject : 定義對象屬性的屬性動畫。用于屬性值不是整型與浮點型的,例如Rect對象。
setDuration : 設定動畫的持續時間。
setInterpolator : 設定動畫的插值器。
start : 開始播放動畫。
屬性動畫組合AnimatorSet
AnimationSet用來組裝補間動畫,而用于組裝屬性動畫的另有其人,它就是AnimatorSet。AnimatorSet組裝屬性動畫是通過内部類Builder實作的,下面是AnimationSet.Builder的組裝方法:
with : 與目前動畫一起播放。
before : 在目前動畫之前播放。
after : 在目前動畫之後播放。
下面是AnimatorSet的常用方法:
setDuration : 設定動畫的持續時間。
setInterpolator : 設定動畫的插值器。
play : 設定初始動畫,即目前動畫。該方法傳回AnimationSet.Builder對象,可對Builder對象添加新的屬性動畫,進而實作組裝功能。
start : 開始播放動畫。
pause : 暫停播放。
resume : 恢複播放。
cancel : 取消播放。
end : 結束播放。end方法與cancel方法的差別在于:cancel方法會觸發AnimatorListener的onAnimationCancel事件,而end方法不會觸發該事件。
isRunning : 判斷動畫是否在播放。
插值器和估值器
插值器
插值器用來控制屬性變化的速率,也可以了解為動畫播放的速度,預設是勻速播放。要設定一個插值器,調用setInterpolator方法即可,不管是補間動畫、還是集合動畫、還是屬性動畫、還是屬性動畫組合,都可以設定插值器。
下面是插值器具體實作類的說明:
LinearInterpolator : 勻速
AccelerateInterpolator : 加速
DecelerateInterpolator : 減速
AccelerateDecelerateInterpolator : 鐘擺速度,即前半段加速、後半段減速
AnticipateInterpolator : 後退幾步再往前沖
AnticipateOvershootInterpolator : 後退幾步再往前沖,沖過頭再歸位
BounceInterpolator : 皮球落地(落地後會彈起幾次)
CycleInterpolator : 以開始位置為中線而晃動(類似搖擺,開始位置與結束位置的距離就是搖擺的幅度)
OvershootInterpolator : 沖過頭再歸位
估值器
估值器專用于屬性動畫,主要是描述該屬性的數值變化要采用什麼機關,比如說整型數的漸變數值都要取整,顔色的漸變數值要按照RGB格式取整,矩形的漸變數值要同時對橫坐标和縱坐标取整等等。要設定屬性動畫的估值器,調用ObjectAnimator的setEvaluator方法即可。
下面是估值器具體實作類的說明(如果屬性類型是自定義的,那也得自定義對應的估值器):
IntEvaluator : 整型估值器
FloatEvaluator : 浮點型估值器
ArgbEvaluator : 顔色估值器
RectEvaluator : 矩形估值器
屬性方法與估值器的對應關系
為友善記憶屬性動畫中屬性方法與估值器的關系,下面列出相關對象的對應關系:
ofInt——IntEvaluator——顔色
ofInt——ArgbEvaluator——顔色,如backgroundColor、textColor等等
ofFloat——FloatEvaluator——大部分屬性,如alpha、rotation、scaleY、translationX等等
ofObject——RectEvaluator——範圍,如clipBounds
代碼例子
下面是集合動畫的代碼示例
import com.example.exmanimation.util.MetricsUtil;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
public class SetActivity extends Activity implements OnClickListener, AnimationListener {
private final static String TAG = "SetActivity";
private ImageView iv_set;
private Animation translateAnimation, alphaAnimation, scaleAnimation, rotateAnimation;
private AnimationSet setAnimation;
private Animation translateAnimation9;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set);
Button btn_set_start = (Button) findViewById(R.id.btn_set_start);
Button btn_translate_start = (Button) findViewById(R.id.btn_translate_start);
btn_set_start.setOnClickListener(this);
btn_translate_start.setOnClickListener(this);
iv_set = (ImageView) findViewById(R.id.iv_set);
translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f,
MetricsUtil.dip2px(this, 250));
translateAnimation.setDuration(3000);
translateAnimation.setFillAfter(true);
translateAnimation.setInterpolator(new AccelerateInterpolator());
alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
alphaAnimation.setDuration(3000);
alphaAnimation.setFillAfter(true);
scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 1.0f);
scaleAnimation.setDuration(3000);
scaleAnimation.setFillAfter(true);
rotateAnimation = new RotateAnimation(0f, 360f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_translate_start) {
translateAnimation9 = new TranslateAnimation(0.1f, 0.1f, 0.1f,
MetricsUtil.dip2px(this, 250));
translateAnimation9.setDuration(3000);
translateAnimation9.setFillAfter(true);
translateAnimation9.setInterpolator(new AccelerateInterpolator());
iv_set.startAnimation(translateAnimation9);
translateAnimation9.setAnimationListener(this);
} else if (v.getId() == R.id.btn_set_start) {
setAnimation = new AnimationSet(true);
setAnimation.addAnimation(translateAnimation);
setAnimation.addAnimation(alphaAnimation);
setAnimation.addAnimation(scaleAnimation);
setAnimation.addAnimation(rotateAnimation);
setAnimation.setFillAfter(true);
iv_set.startAnimation(setAnimation);
setAnimation.setAnimationListener(this);
}
}
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Animation translateAnimation2 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);
translateAnimation2.setDuration(3000);
translateAnimation2.setFillAfter(true);
Animation alphaAnimation2 = new AlphaAnimation(0.1f, 1.0f);
alphaAnimation2.setDuration(3000);
alphaAnimation2.setFillAfter(true);
Animation scaleAnimation2 = new ScaleAnimation(0.1f, 1.0f, 1.0f, 1.0f);
scaleAnimation2.setDuration(3000);
scaleAnimation2.setFillAfter(true);
Animation rotateAnimation2 = new RotateAnimation(0f, -360f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation2.setDuration(3000);
rotateAnimation2.setFillAfter(true);
if (animation.equals(translateAnimation9)) {
Animation translateAnimation10 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);
translateAnimation10.setDuration(3000);
translateAnimation10.setFillAfter(true);
translateAnimation10.setInterpolator(new DecelerateInterpolator());
iv_set.startAnimation(translateAnimation10);
} else if (animation.equals(setAnimation)) {
AnimationSet setAnimation2 = new AnimationSet(true);
setAnimation2.addAnimation(translateAnimation2);
setAnimation2.addAnimation(alphaAnimation2);
setAnimation2.addAnimation(scaleAnimation2);
setAnimation2.addAnimation(rotateAnimation2);
setAnimation2.setFillAfter(true);
iv_set.startAnimation(setAnimation2);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
下面是屬性動畫及屬性動畫組合的代碼示例
import com.example.exmanimation.util.MetricsUtil;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
public class SetActivity extends Activity implements OnClickListener, AnimationListener {
private final static String TAG = "SetActivity";
private ImageView iv_set;
private Animation translateAnimation, alphaAnimation, scaleAnimation, rotateAnimation;
private AnimationSet setAnimation;
private Animation translateAnimation9;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set);
Button btn_set_start = (Button) findViewById(R.id.btn_set_start);
Button btn_translate_start = (Button) findViewById(R.id.btn_translate_start);
btn_set_start.setOnClickListener(this);
btn_translate_start.setOnClickListener(this);
iv_set = (ImageView) findViewById(R.id.iv_set);
translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f,
MetricsUtil.dip2px(this, 250));
translateAnimation.setDuration(3000);
translateAnimation.setFillAfter(true);
translateAnimation.setInterpolator(new AccelerateInterpolator());
alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
alphaAnimation.setDuration(3000);
alphaAnimation.setFillAfter(true);
scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 1.0f);
scaleAnimation.setDuration(3000);
scaleAnimation.setFillAfter(true);
rotateAnimation = new RotateAnimation(0f, 360f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_translate_start) {
translateAnimation9 = new TranslateAnimation(0.1f, 0.1f, 0.1f,
MetricsUtil.dip2px(this, 250));
translateAnimation9.setDuration(3000);
translateAnimation9.setFillAfter(true);
translateAnimation9.setInterpolator(new AccelerateInterpolator());
iv_set.startAnimation(translateAnimation9);
translateAnimation9.setAnimationListener(this);
} else if (v.getId() == R.id.btn_set_start) {
setAnimation = new AnimationSet(true);
setAnimation.addAnimation(translateAnimation);
setAnimation.addAnimation(alphaAnimation);
setAnimation.addAnimation(scaleAnimation);
setAnimation.addAnimation(rotateAnimation);
setAnimation.setFillAfter(true);
iv_set.startAnimation(setAnimation);
setAnimation.setAnimationListener(this);
}
}
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Animation translateAnimation2 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);
translateAnimation2.setDuration(3000);
translateAnimation2.setFillAfter(true);
Animation alphaAnimation2 = new AlphaAnimation(0.1f, 1.0f);
alphaAnimation2.setDuration(3000);
alphaAnimation2.setFillAfter(true);
Animation scaleAnimation2 = new ScaleAnimation(0.1f, 1.0f, 1.0f, 1.0f);
scaleAnimation2.setDuration(3000);
scaleAnimation2.setFillAfter(true);
Animation rotateAnimation2 = new RotateAnimation(0f, -360f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation2.setDuration(3000);
rotateAnimation2.setFillAfter(true);
if (animation.equals(translateAnimation9)) {
Animation translateAnimation10 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);
translateAnimation10.setDuration(3000);
translateAnimation10.setFillAfter(true);
translateAnimation10.setInterpolator(new DecelerateInterpolator());
iv_set.startAnimation(translateAnimation10);
} else if (animation.equals(setAnimation)) {
AnimationSet setAnimation2 = new AnimationSet(true);
setAnimation2.addAnimation(translateAnimation2);
setAnimation2.addAnimation(alphaAnimation2);
setAnimation2.addAnimation(scaleAnimation2);
setAnimation2.addAnimation(rotateAnimation2);
setAnimation2.setFillAfter(true);
iv_set.startAnimation(setAnimation2);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
點選下載下傳本文用到的集合動畫與屬性動畫的工程代碼
點此檢視Android開發筆記的完整目錄