一、概述
上一節我們分析了Frame動畫,本節我們結合執行個體,繼續分析Tween動畫。Tween動畫隻需要指定動畫的開始幀、結束幀以及持續時間,中間幀由系統自動計算完成。Tween動畫對應的類是Animation,它是抽象類,我們使用的是它的子類,繼承關系如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM4kTO1UDN5ADNycDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
動畫類 xml節點 功能
ScaleAnimation | <scale> | 大小伸縮效果 |
TranslateAnimation | <translate> | 位置移動效果 |
AlphaAnimation | <alpha> | 透明度漸變效果 |
RotateAnimation | <rotate> | 旋轉效果 |
AnimationSet | <set> | 持有alpah、scale、translate、rotate或者其他set元素的動畫集合 |
Animation是四類Tween動畫的父類,是以它有一些公共屬性,如下:
Java方法 xml屬性 屬性功能
setDuration(long) | android:duration | 設定動畫持續時間,機關為毫秒 |
setFillAfter(boolean) | android:fillAfter | 動畫結束時控件是否保持動畫最後狀态 |
setFillBefore(boolean) | android:fillBefore | 動畫結束時控件是否還原到開始動畫時的狀态 |
setFillEnable(boolean) | android:fillEnable(boolean) | 與android:fillBefore效果相同 |
setInterpolator(boolean) | android:interpolator | 設定插值器,動畫變化快慢程度 |
setRepeatCount(int) | android:repeatCount | 重複次數 |
setRepeatMode(int) | android:repeatMode | 重複類型:reverse倒序回放、restart從頭播放 |
setStartOffset(long) | android:startOffset | 調用start函數後,等待多長時間後再運作動畫,機關為毫秒 |
由于Animation類是抽象父類,那麼我們使用的補間動畫無論是哪一種都已經具備了以上屬性。
二、四類補間動畫
補間動畫demo截圖:
代碼GitHub位址:https://github.com/xiyy/CityOfAnimation
ScaleAnimation
1、xml實作動畫
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
duration : 動畫持續時間,機關毫秒
fromXScale : 初始X軸縮放比例
fromYScale : 初始Y軸放縮比例
toXScale : 結束時X軸放縮比例
toYScale : 結束時Y軸放縮比例
pivotX : 縮放起點X軸坐标
可以是數值、百分數、百分數p,譬如50表示以目前View左上角坐标x值加50px為初始點、50%表示以目前View的左上角加上目前View寬的50%做為初始點、50%p表示以目前View的左上角加上父控件寬的50%做為初始點。
pivotY : 縮放起點Y軸坐标,規律同pivotX
2 xml屬性與構造方法參數對應
構造方法參數 xml屬性
ScaleAnimation(float fromX, …) | android:fromXScale |
ScaleAnimation(…, float toX) | android:toXScale |
ScaleAnimation(…, …, float fromY, …) | androd:fromYScale |
ScaleAnimation(…, …, …, float toY) | android:toYScale |
ScaleAnimation(…, float pivotX, …) | android:pivotX |
ScaleAnimation(…, float pivotY) | android:pivotY |
3 Java代碼
private void scaleAnimation() {
//xml檔案中,pivotX、pivotY代表從哪個點開始縮放,含義和rotateAnimation()中4、6參數相同
if (mScale1.isChecked()) {
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_activity_scale_1);
} else if (mScale2.isChecked()) {
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_activity_scale_2);
} else {
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_activity_scale_3);
}
setProperty();
mImageIcon.startAnimation(mAnimation);
}
上述動畫,View在1秒内,從無變化到原始大小,縮放起點是view中心
TranslateAnimation
1 xml實作動畫
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXDelta="50%"
android:fromYDelta="50%"
android:toXDelta="100"
android:toYDelta="100">
</translate>
duration:動畫持續時間,機關毫秒
(fromXDelta,fromYDelta):移動起始位置
(toXDelta,toYDelta):移動結束位置
view左上角在duration内從起始位置移動到結束位置
fromXDelta:可以是數值、百分數、百分數p,譬如50表示以目前View左上角坐标x值加50px為初始點、50%表示以目前View的左上角加上目前View寬的50%做為初始點、50%p表示以目前View的左上角加上父控件寬的50%做為初始點。
fromYDelta、toXDelta、toYDelta含義和fromXDelta相同
2 xml屬性和構造方法參數對應
TranslateAnimation(float fromXDelta, …) | android:fromXDelta |
TranslateAnimation(…, float toXDelta) | android:toXDelta |
TranslateAnimation(…, float fromYDelta, …) | android:fromYDelta |
TranslateAnimation(…, float toYDelta) | android:toYDelta |
3 Java代碼
private void translateAnimation() {
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_activity_translate);
setProperty();
mImageIcon.startAnimation(mAnimation);
}
上述動畫,view在300毫秒内,從現有位置向右移動100像素的同時向下移動100像素
AlphaAnimation
1 xml動畫實作
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toAlpha="0.0" />
1秒内,View從完全不透明到完全透明;interpolator是插值器,後面會具體講述
2 構造方法參數和xml屬性對應
JAVA方法 | XML屬性 | 解釋 |
AlphaAnimation(float fromAlpha,…) | android:fromAlpha | 動畫開始的透明度(0.0到1.0,0.0是全透明,1.0是不透明) |
AlphaAnimation(…, float toAlpha) | androdi:toAlpha | 動畫結束的透明度(同上) |
3 Java代碼
private void alphaAnimation() {
mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_activity_alpha);
setProperty();
mImageIcon.startAnimation(mAnimation);
}
上述動畫,view在1秒内,從完全不透明過渡到完全透明
RotateAnimation
1 xml屬性與構造方法參數對應
JAVA方法 | XML屬性 | 解釋 |
RotateAnimation(float fromDegrees, …) | android:fromDegress | 旋轉開始角度,正代表順時針度數,負代表逆時針度數 |
RotateAnimation(…, float toDegress) | android:toDegress | 旋轉結束角度(同上) |
RotateAnimation(…, …, float pivotX, …) | android:pivotX | 旋轉點X坐标了,可以是數值、百分數、百分數p,如50表示以目前View左上角x坐标加50px為旋轉點、50%表示以目前View的左上角加上目前View寬高的50%做為旋轉點、50%p表示以目前View的左上角加上父控件寬高的50%做為旋轉點。 |
RotateAnimation(…, …, …, pivotY) | android:pivotY | 旋轉點Y坐标(同上) |
2 Java代碼實作
private void rotateAnimation() {
//第4和第6個參數,決定了圖像圍繞哪個點旋轉,如(0,0),則圖像圍繞左上頂點旋轉;(0.2,0.5),
// 則圖像圍繞(0.2*imageView.width,0.5*imageView.height)旋轉;(0.5,0.5)則圖像圍繞圖像中心旋轉;
//(1.0,1.0),則圖像圍繞右下頂點旋轉;
//參數3,5代表相對本身旋轉
mAnimation = new RotateAnimation(-degree, degree, Animation.RELATIVE_TO_SELF,
pivotXValue, Animation.RELATIVE_TO_SELF, pivotYValue);
mAnimation.setDuration((int) time);
setProperty();
mImageIcon.startAnimation(mAnimation);
}
三、Animation、View常用API
Animation類的方法 | 解釋 |
reset() | 重置Animation的初始化 |
cancel()/stop() | 取消/停止Animation動畫 |
start() | 開始Animation動畫 |
setAnimationListener(AnimationListener listener) | 給目前Animation設定動畫監聽 |
hasStarted() | 判斷目前Animation是否開始 |
hasEnded() | 判斷目前Animation是否結束 |
View類的常用動畫操作方法 | 解釋 |
startAnimation(Animation animation) | view設定Animation動畫并開始執行 |
clearAnimation() | 取消View在執行的Animation動畫 |
四、插值器Interpolator
Interpolator負責控制動畫的變化速度,這就使得基本的動畫效果(Alpha、Scale、Translate、Rotate)能以勻速變化、加速、減速、抛物線等各種速度變化。Interpolator是一個接口,它定義了所有Interpolator都必須實作的方法:float getInterpolator(float input),開發者完全可以通過實作Interpolator來控制動畫的變化速度。Android為Interpolator提供了如下幾個實作類,分别用于實作不同的動畫變化速度。
java類 | xml id值 | 描述 |
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 動畫始末速率較慢,中間加速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 動畫開始速率較慢,之後慢慢加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 開始的時候從後向前甩 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 類似上面AnticipateInterpolator |
BounceInterpolator | @android:anim/bounce_interpolator | 動畫結束時彈起 |
CycleInterpolator | @android:anim/cycle_interpolator | 循環播放速率改變為正弦曲線 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 動畫開始快然後慢 |
LinearInterpolator | @android:anim/linear_interpolator | 動畫勻速改變 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 向前彈出一定值之後回到原來位置 |
PathInterpolator | 新增,定義路徑坐标後按照路徑坐标來跑。 |
五、補間動畫分析
Tween動畫隻能對View進行移動、縮放、旋轉和淡入淡出等簡單操作,一旦我們的需求超出了移動、縮放、旋轉和淡入淡出這四種對View的操作,那麼補間動畫就不能再幫我們忙了,也就是說它在功能和可擴充方面都有相當大的局限性。此外,Tween動畫隻是改變了View的顯示效果而已,并不會真正的改變View的屬性。具體來說,例如螢幕左上角有一個Button,使用補間動畫将其移動到右下角,此刻你去點選右下角的Button,它是絕對不會響應點選事件的,是以其作用區域依然還在左上角。隻不過是補間動畫将其繪制在右下角而已。
是以Tween動畫适用于移動、縮放、旋轉和淡入淡出這四種操作,并且動畫過程中不需要響應點選事件,其他動畫場景考慮Frame動畫或者Property動畫。
本節代碼GitHub位址:https://github.com/xiyy/CityOfAnimation,下一節,我們一起來分析屬性動畫,歡迎關注!