天天看點

Android開發筆記(九十六)集合動畫與屬性動畫集合動畫AnimationSet屬性動畫ObjectAnimator屬性動畫組合AnimatorSet插值器和估值器代碼例子

集合動畫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開發筆記的完整目錄

繼續閱讀