屬性動畫和檢視動畫
安卓中動畫主要包括兩大類:view檢視動畫和property屬性動畫
而view動畫又分為兩種:Frame逐幀動畫和Tween補間動畫
Frame逐幀動畫:主要用於簡單的動畫,就像放電影一樣一幀一幀的播放對應的圖片,生成類似於GIF動態圖效果。DrawableAnimation也是指此類動畫
Tween補間動畫:主要包括四種動畫Alpha透明度,Translate位移,Rotate旋轉,Scale縮放效果
view檢視動畫相比屬性動畫,有一個很大的區別特點:檢視動畫只是顯示位置的變化,view的實際位置並未改變,表現為view移動到其他地方,點選事件仍在原來的地方才能響應。而屬性動畫恰恰相反(注android 3.0 API 11 後才出現的屬性動畫)
Property屬性動畫:
該動畫有一些相關類組成。
1.ObjectAnimator :物件動畫執行類。
2.ValueAnimator :值動畫執行類,常配合AnimatorUpdateListener使用。 3.PropertyValuesHolder : 屬性儲存器,為兩個執行類提供更新多個屬性的功能。 4.Keyframe :為 PropertyValuesHolder提供多個關鍵幀的操作值。 5.AnimatorSet :一組動畫的執行集合類:設定執行的先後順序,時間等。 6.AnimatorUpdateListener1.ObjectAnimator物件動畫執行類
介紹: 1. 通過靜態方法ofInt、ofFloat、ofObject、ofPropertyValuesHolder 獲取類物件。 2. 根據屬性值型別選擇靜態方法,如view的setLeft(int left) 則選用ofInt方法, setY(float y)則選用ofFloat方法。 3. 同ValueAnimator一樣,可以進行串聯式使用,示例如下。
第一個簡單示例:View的橫向移動
// 通過靜態方法構建一個ObjectAnimator物件
// 設定作用物件、屬性名稱、數值集合
ObjectAnimator.ofFloat(view, "translationX", 0.0F, 200.0F)
// 設定執行時間(1000ms)
.setDuration(1000)
// 開始動畫
.start();
第二個複雜點的示例:View彈性落下然後彈起,執行一次。
// 修改view的y屬性, 從當前位置移動到300.0f
ObjectAnimator yBouncer = ObjectAnimator.ofFloat(view, "y",
view.getY(), 300.0f);
yBouncer.setDuration(1500);
// 設定插值器(用於調節動畫執行過程的速度)
yBouncer.setInterpolator(new BounceInterpolator());
// 設定重複次數(預設為0,表示不重複執行)
yBouncer.setRepeatCount(1);
// 設定重複模式(RESTART或REVERSE),重複次數大於0或INFINITE生效
yBouncer.setRepeatMode(ValueAnimator.REVERSE);
// 設定動畫開始的延時時間(200ms)
yBouncer.setStartDelay(200);
// 開始動畫
yBouncer.start();
2.ValueAnimator 值動畫執行類
介紹: 1. 構造方法與ObjectAnimator類似。 2. 與ObjectAnimator的區別在於ValueAnimator建構函式的引數中不包含動畫“屬性”資訊。 3. 優點:結合動畫更新監聽onAnimationUpdate使用,可以在回撥中不斷更新View的多個屬性,使用起來更加靈活。 第三個示例View向右下角移動: // 通過靜態方法構建一個ValueAnimator物件
// 設定數值集合
ValueAnimator animator = ValueAnimator.ofFloat(0f, 200.0f);
// 設定作用物件
animator.setTarget(view);
// 設定執行時間(1000ms)
animator.setDuration(1000);
// 新增動畫更新監聽
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 獲取當前值
Float mValue = (Float) animation.getAnimatedValue();
// 設定橫向偏移量
view.setTranslationX(mValue);
// 設定縱向偏移量
view.setTranslationY(mValue);
}
});
// 開始動畫
animator.start();
3.PropertyValuesHolder 屬性儲存器
介紹: 為ValueAnimator提供多個操作屬性及相應的執行引數。 第四個示例:同時修改View多個屬性的動畫
// 獲取view左邊位置
int left = view.getLeft();
// 獲取view右邊位置
int right = view.getRight();
// 將view左邊增加10畫素
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", left,
left + 10);
// 將view右邊減少10畫素
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right",
right, right - 10);
// 在X軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f
PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX",
1f, 0f, 1f);
// 在Y軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f
PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY",
1f, 0f, 1f);
// 將PropertyValuesHolder交付給ObjectAnimator進行構建
ObjectAnimator customAnim = ObjectAnimator.ofPropertyValuesHolder(view,
pvhLeft, pvhRight, pvhScaleX, pvhScaleY);
// 設定執行時間(1000ms)
customAnim.setDuration(1000);
// 開始動畫
customAnim.start();
4.Keyframe 關鍵幀
介紹: 為 PropertyValuesHolder提供關鍵幀的操作值集合。 第五個示例:以下示例表示該PropertyValuesHolder進行的旋轉(rotation)動畫,在執行時間在0%, 50%, 100%時,其旋轉角度分別為0°, 360°, 0°。動畫執行過程中自動進行補間。表現為自旋360°後再轉回來。
// 設定在動畫開始時,旋轉角度為0度
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
// 設定在動畫執行50%時,旋轉角度為360度
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
// 設定在動畫結束時,旋轉角度為0度
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
// 使用PropertyValuesHolder進行屬性名稱和值集合的封裝
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(
"rotation", kf0, kf1, kf2);
// 通過ObjectAnimator進行執行
ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation)
// 設定執行時間(1000ms)
.setDuration(1000)
// 開始動畫
.start();
5.AnimatorSet 執行集合類
介紹: 1. 為多個屬性動畫提供播放順序控制(注意play,with,after,before的用法)。 2. AnimatorSet類與AnimationSet類不能搞混,AnimatorSet在3.0及以上版本中才有。3.0之前的版本可使用第三方開源庫nineoldandroids.jar進行支援,功能使用完全一致。 第六個示例:以下示例動畫的播放順序為
1.播放 bounceAnim;
2.同時播放 squashAnim1, squashAnim2,stretchAnim1, stretchAnim2;
3.接著播放 bounceBackAnim; 4.最後播放 fadeAnim; AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();
詳細程式碼參見:http://developer.android.com/guide/topics/graphics/prop-animation.html
6. AnimatorUpdateListener動畫更新監聽
介紹: 1.在動畫執行過程中,每次更新都會呼叫該回調,可以在該回調中手動更新view的屬性。 2.當呼叫的屬性方法中沒有進行View的重繪時,需要進行手動觸發重繪。設定AnimatorUpdateListener監聽,並在onAnimationUpdate回撥中執行View的invalidate()方法。 第七個示例:在回撥中手動更新View對應屬性:
// 1. 在回撥中手動更新View對應屬性:
AnimatorUpdateListener l = new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
// 當前的分度值範圍為0.0f->1.0f
// 分度值是動畫執行的百分比。區別於AnimatedValue。
float fraction = animation.getAnimatedFraction();
// 以下的的效果為 View從完全透明到不透明,
view.setAlpha(fraction);
// Y方向向下移動300px的距離.
view.setTranslationY(fraction * 300.0f);
}
};
ValueAnimator mAnim = ValueAnimator.ofFloat(0f, 1.0f);
mAnim.addUpdateListener(l);
mAnim.setDuration(1000);
mAnim.start();
第八個示例:在自定義View內部用於引發重繪:
// 2. 在自定義View內部用於引發重繪
public class MyAnimationView extends View implements
ValueAnimator.AnimatorUpdateListener {
public MyAnimationView(Context context) {
super(context);
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 手動觸發介面重繪
invalidate();
}
}
7.AnimatorListener 動畫執行監聽
介紹: 1. 實現AnimatorListener中的方法可在動畫執行全程進行其他任務的回撥執行。 2. 也可以新增AnimatorListener的實現類AnimatorListenerAdapter,僅重寫需要的監聽即可。 第九個示例:
// 將view透明度從當前的1.0f更新為0.5f,在動畫結束時移除該View
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.setDuration(1000);
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// 動畫開始時呼叫
}
@Override
public void onAnimationRepeat(Animator animation) {
// 動畫重複時呼叫
}
@Override
public void onAnimationEnd(Animator animation) {
// 動畫結束時呼叫
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
@Override
public void onAnimationCancel(Animator animation) {
// 動畫取消時呼叫
}
});
anim.start();
8.AnimatorInflater 動畫載入器
介紹: 1. 屬性動畫可以通過xml檔案的形式載入。 2. set標籤內的animator也可單獨使用。 3. XML語法如下: <setandroid:ordering=["together" ¦ "sequentially"]>
<objectAnimator
android:propertyName="string"
android:duration="int"
android:valueFrom="float¦ int ¦ color"
android:valueTo="float¦ int ¦ color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat"¦ "reverse"]
android:valueType=["intType"¦ "floatType"]/>
<animator
android:duration="int"
android:valueFrom="float¦ int ¦ color"
android:valueTo="float¦ int ¦ color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat"¦ "reverse"]
android:valueType=["intType"¦ "floatType"]/>
<set>
...
</set>
</set>
示例如下:
// 載入xml屬性動畫
Animator anim = AnimatorInflater
.loadAnimator(this, R.anim.animator_set);
anim.setTarget(view);
anim.start();
xml檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="x"
android:repeatCount="1"
android:repeatMode="reverse"/>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="400"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>
</set>
9.TypeEvaluator 型別估值
介紹: 1. TypeEvaluator可傳入引數值的型別(本例為PointF)。 2. 重寫函式public T evaluate(floatfraction, T startValue, T endValue);實現不同需求值的計算。 3. 注意fraction的使用,fraction是從開始到結束的分度值0.0 -> 1.0。 示例:
// 型別估值 - 拋物線示例
TypeEvaluator<PointF> typeEvaluator = new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue) {
float time = fraction * 3;
Log.e(TAG, time + "");
// x方向200px/s ,y方向0.5 * 200 * t * t
PointF point = new PointF();
point.x = 120 * time;
point.y = 0.5f * 200 * time * time;
return point;
}
};
ValueAnimator valueAnimator = ValueAnimator.ofObject(typeEvaluator,
new PointF(0, 0));
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(3000);
valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
view.setX(point.x);
view.setY(point.y);
}
});
10. TimeInterpolator 時間插值器
1. 幾種常見的插值器: Interpolator物件 資源ID 功能作用
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速再減速
AccelerateInterpolator @android:anim/accelerate_interpolator 加速
AnticipateInterpolator @android:anim/anticipate_interpolator 先回退一小步然後加速前進
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 在上一個基礎上超出終點一小步再回到終點
BounceInterpolator @android:anim/bounce_interpolator 最後階段彈球效果
CycleInterpolator @android:anim/cycle_interpolator @android:anim/cycle_interpolator
DecelerateInterpolator @android:anim/decelerate_interpolator 減速
LinearInterpolator @android:anim/linear_interpolator 勻速
OvershootInterpolator @android:anim/overshoot_interpolator 快速到達終點並超出一小步最後回到終點
2. 自定義插值器 a.實現Interpolator(TimeInterpolator)介面; b.重寫介面函式float getInterpolation(floatinput)。